如何打印包含字段分隔符的最后一个单词

如何打印包含字段分隔符的最后一个单词

如何打印word3,a,b,c,d,e包含字段分隔符的最后一个字段 ( ) ,

  • 每行只有 3 个单词/字符串,结构如下

    类型、参数、值

但该值可以包含未转义的字段分隔符本身。行示例:

echo word1,word2,word3,a,b,c,d,e | awk -F "," '{print $3}'

它的打印:

word3

预期成绩:

word3,a,b,c,d,e

其他例子

echo 32637,921763.373,str84,str42,struj,str56,str65 | awk -F "," '{print $3}'

预期成绩:

str84,str42,struj,str56,str65 

答案1

那么,最后一个字段word1,word2,word3,a,b,c,d,ee,第三个字段是word3。看来您想要从第三个字段开始的行部分。使用以下方法更容易cut

$ echo word1,word2,word3,a,b,c,d,e | cut -d , -f 3-
word3,a,b,c,d,e

-f 3-适用-f x-y于字段 x 到 y,但省略y,因此它是从第 3 个字段到最后一个字段。

请注意,它假定这些行至少包含 3 个字段。它将为包含 2 个字段的输入行提供空输出行,如果不包含逗号,则保持该行不变(您可以添加一个-s选项来跳过非分隔行):

$ printf '%s\n' a a,b a,b,c a,b,c,d | cut -d , -f 3-
a

c
c,d
$ printf '%s\n' a a,b a,b,c a,b,c,d | cut -sd , -f 3-

c
c,d

有了awk,你可以这样做:

$ printf '%s\n' a a,b a,b,c a,b,c,d | awk 'sub(/^[^,]*,[^,]*,/, "")'
c
c,d

awk 'sub(/^([^,]*,){2}/, "")'尽管该变体是 POSIX,但可移植性较差,因为仍然有一些awk实现不支持{x,y}正则表达式运算符)

要删除前 2 个字段(并且仅打印已删除的行),尽管这将用作awk美化sed,因为与sed -n 's/^[^,]*,[^,]*,//p'.

或者:

$ printf '%s\n' a a,b a,b,c a,b,c,d | awk 'sub(/^[^,]*,?[^,]*,?/, "")'


c
c,d

对于少于 3 个字段的行打印空行。

答案2

方法awk是:

awk -F "," '{for(i=3;i<NF;i++)printf("%s,", $i);print $NF}'

但这听起来像是一份工作cut

cut -d , -f 3-

答案3

使用,利用其数组切片功能(避免像 中那样perl需要循环):forawk

$ echo word1,word2,word3,a,b,c,d,e | perl -F, -lane 'print join(",",@F[2..$#F])'
word3,a,b,c,d,e

perl使用的命令行选项的说明(man perlrun更多详细信息,请参阅 参考资料):

  • -F,将自动分割的字段分隔符设置为,
  • -l启用自动行结束处理(即自动从每个输入行的末尾去除换行符并将它们添加到每个print-ed 输出行)。
  • -a打开自动分割模式 - 每个输入行自动分割成一个数组@F
  • -n读取并处理每一行标准输入和/或任何文件名参数(本质上是while(<>)围绕整个脚本的循环)
  • -e将下一个参数(带引号的字符串)作为 perl 脚本执行。

注意:perl数组是从零开始的,而不是从一开始的,因此第三个字段是数组元素 2,而不是 3(即@F[2],不是 @F[3])。

$#F是 array 最后一个元素的索引号@F,因此@F[2..$#F]表示“数组中@F从第三个到最后一个的所有元素”。


顺便说一句,还有另一个选项-p非常相似,-n除了在每次循环结束时while(<>),它还会打印输入行。如果输入行已被任何先前的语句修改,则该行将按修改后的状态打印。

其用途之一是它允许您编写非常sed类似的脚本(但具有除 之外的perl所有功能和语法糖)。例如,在给定相同的输入的情况下,将具有相同的输出。perlsedperl -pe 's/foo/bar/g'sed -e 's/foo/bar/g'

同样,-n结合使用-a可以轻松编写非常awk相似的脚本。事实上,perl -lane这几乎是用 编写awk类似单行的标准方法perl

的优点之一是它结合了 和的perl功能以及更多功能,包括访问称为“综合 Perl 存档网络”或的巨大模块库sedawktrCPAN

答案4

使用sed

sed 's/^\([^,]*,\)\{0,2\}//' <<<"$line"

相关内容