如何打印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,e
是e
,第三个字段是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
需要循环):for
awk
$ 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
所有功能和语法糖)。例如,在给定相同的输入的情况下,将具有相同的输出。perl
sed
perl -pe 's/foo/bar/g'
sed -e 's/foo/bar/g'
同样,-n
结合使用-a
可以轻松编写非常awk
相似的脚本。事实上,perl -lane
这几乎是用 编写awk
类似单行的标准方法perl
。
的优点之一是它结合了 和的perl
功能以及更多功能,包括访问称为“综合 Perl 存档网络”或的巨大模块库sed
awk
tr
CPAN
答案4
使用sed
:
sed 's/^\([^,]*,\)\{0,2\}//' <<<"$line"