使用awk在单个空格而不是多个空格上拆分一行

daz*_*sed 8 shell ksh awk quoting columns

我试图分割一条我无法控制其格式的行。如果缺少参数 7 和 8,它们可能会被一个空格替换,所以我最终会得到,

field1 field2 field3 field4 field5 field6   field9
Run Code Online (Sandbox Code Playgroud)

目前在这种情况下,字段 9 被读取为字段 7。大量搜索使我相信以下内容应该有效,但实际上并没有。这可能是我的一些小语​​法错误,但我似乎无法发现它。

word1=`echo $LINE | awk 'BEGIN { FS="[ ]" } ; { print $9 }'`
Run Code Online (Sandbox Code Playgroud)

llu*_*lua 9

LINE 参数没有被引用,因此wordsplitting$LINEin扩展时发生,echo $LINE并且在awk接收任何输入时,您有 7 个words(如 shell 所见)全部由一个空格分隔。您希望 echo 将其作为一个输出word(再次,如 shell 所见),因此在 awk 可以处理它之前,您的行中的空白不会被破坏。这就是引用参数所阻止的。

# How you want it to be given to awk:
$ printf '<%s> ' "$LINE"; echo
<field1 field2 field3 field4 field5 field6   field9> 
# Your attempt:
$ printf '<%s> ' $LINE; echo
<field1> <field2> <field3> <field4> <field5> <field6> <field9> 
Run Code Online (Sandbox Code Playgroud)

注意字段 6 和 9 之间的额外空白是如何消失的。

你应该总是引用扩展,不引用扩展比引用它们更有可能破坏某些东西。


HBr*_*ijn 6

在处理可变输入长度时,awk 中一个非常有用的参数是 NF,即字段数。

lastword=`echo $LINE | awk '{ print $NF }'`
Run Code Online (Sandbox Code Playgroud)

这将始终打印最后一列,而不管缺少的列。如果中间的某些字段丢失,从最后一个字段开始倒数也很有效。

一个示例文件,其中缺少/空列填充了空格,例如您的示例:

line1 field1 field2 field3 field4 field5 field6 field7 field8 field9
line2 field1 field2 field3 field4 field5 field6  field8 field9
line3 field1 field2 field3 field4 field5   field8 field9
Run Code Online (Sandbox Code Playgroud)

awk '{print $1 " " $2 " " $(NF-1) " " $NF}' file

    line1 field1 field8 field9
    line2 field1 field8 field9
    line3 field1 field8 field9
Run Code Online (Sandbox Code Playgroud)