如何使用 awk 在两个位置参数之间进行打印

如何使用 awk 在两个位置参数之间进行打印

有没有办法使用 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 perlvarperldoc 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

相关内容