有没有办法使用 awk 打印位置参数后的所有内容?我想要以下命令打印的是“p4 p5 p6 p7”
echo p1 p2 p3 p4 p5 p6 p7 | awk '{print $4...}'
此外,是否可以在两个位置参数之间进行打印。下面打印“p4 p5 p6”
echo p1 p2 p3 p4 p5 p6 p7 | awk '{print $4...$6}'
我想避免使用正则表达式并必须输入: awk '{print $4" "$5" "$6}'
答案1
awk
不能做到这一点(不使用某种循环),但是perl
可以。
但请记住,perl
数组是从零开始的(而awk
数组索引从 1 开始)。
例如,使用perl
's-a
选项进行awk
类似自动分割:
$ echo p1 p2 p3 p4 p5 p6 p7 | perl -lane 'print "@F[3..$#F]";'
p4 p5 p6 p7
$ echo p1 p2 p3 p4 p5 p6 p7 | perl -lane 'print "@F[2,4,6]";'
p3 p5 p7
$ echo p1 p2 p3 p4 p5 p6 p7 | perl -lane 'print "@F[1..3]";'
p2 p3 p4
注意:-l
打开 perl 对行结尾的自动处理,并将-n
其包装在一个循环中,逐行处理输入,而不进行任何自动输出(类似于 sed 的 -n 选项。 -p
执行相同的操作,但自动打印其后的每个输入行已由脚本的其余部分检查和/或修改)。看man perlrun
。
有关数组和数组切片的更多信息,请参阅man perldata
或。perldoc perlvar
由于数组切片是在双引号字符串内打印的,因此它使用$"
aka的值$LIST_SEPARATOR
来分隔数组元素。如果它们在双引号字符串之外打印/使用,则元素之间根本没有分隔符。请参阅man perlvar
或perldoc perlvar
并搜索 LIST_SEPARATOR。
-F
最后,如果您的字段分隔符不是空格(在 PCRE 中),请使用 perl 的选项\s+
,或者自行拆分。例如
$ echo "p1:p2:p3:p4:p5:p6:p7" | perl -F: -lane 'print "@F[0..4]";'
p1 p2 p3 p4 p5
$ echo "p1:p2:p3:p4:p5:p6:p7" | perl -lne '@F=split /:/; print "@F[0..4]";'
p1 p2 p3 p4 p5
答案2
如果您的参数可靠地由一个空格分隔,您可以使用cut
如下:
echo p1 p2 p3 p4 p5 p6 p7 | cut -d' ' -f4- # For p4 onwards
echo p1 p2 p3 p4 p5 p6 p7 | cut -d' ' -f4-6 # For p4 to p6
如果您想要用空格分隔参数,那么解析它们的方式awk
肯定会变得更加复杂。有关我正在谈论的内容以及上述内容如何可能并不总是能达到您想要的效果的示例,请尝试:
printf '%s ' p1 p2 p3 p4 p5 p6 p7 | cut -d' ' -f4-
printf '%s ' p1 p2 p3 p4 p5 p6 p7 | cut -d' ' -f4-6
你可以看到正在cut
治疗每个空格作为分隔符,而不是像这样以任何连续空格序列作为分隔符awk
。您可以awk
使用 for 循环强制执行您想要的操作:
echo p1 p2 p3 p4 p5 p6 p7 | awk '{for (a=4;a<=NF;a++) {printf "%s ", $a} printf "\n"}'
但是,这确实会在行尾留下一个尾随空格。这个问题可以解决,但情况会变得越来越混乱。根据您的要求,该cut
命令可能就可以了。
答案3
这是使用 awk 的 split 函数执行此操作的方法(根据之前的答案,它确实需要 for 循环):
描述:
"sub_0" - variable to contain desired output ($0 substring)
"beg" - 1st desired field (references 4th element in "pn_ary" array)
(external "$beg" shell variable passed into awk (internal "beg" variable)
"end" - # of fields in $0 (split function loads each field in $0 as a "pn_ary[n]" element ("1-n"))
"split(s,a,sep) - "s": string, "a": array, "sep": seperator (splits "s" per "sep", loads "a")
("split" returns # of elements loaded into "pn_ary" array into "end" variable)
"FS" - awk system Field Seperator variable
"[:graph:]" - Posix bracket expression for visible ASCII chars in range "[\x21-\x7E]"
句法:
beg="4"
echo "p1 p2 p3 p4 p5 p6 p7" |\
awk '{sub_0="";end=split($0,pn_ary,FS)
for (i=beg;i<=end;i++) {sub_0=sub_0""FS""pn_ary[i]}
print substr(sub_0,match(sub_0,"[:graph:]"))
}' beg="$beg"
输出:
p4 p5 p6 p7