了解awk中的拆分功能(Shell脚本):

时间:2014-02-18 20:00:53

标签: bash shell awk

RequestID       CustomerID      Status
101     101111  Error
102     323232  Success
103     33434   Error

所以,我正在尝试使用分割选项打印出第一个字段和第二个字段。分隔符是上面的标签。我知道还有其他各种方法,但我正在尝试学习awk中的split函数。我正在尝试以下代码:

awk '{split($1,a,"\t");split($2,b,"\t");print a[1], b[2]}' data

上面的代码只打印第一列($ 1)而不打印列($ 2)。有什么具体的原因吗?

谢谢,

4 个答案:

答案 0 :(得分:1)

正在打印a[1],它是整个第一个字段,而b[2]是空的,因为您要拆分整个第二个字段,例如,'101111'在标签上,将是一个包含一个元素的数组。

除非您更改字段分隔符,否则awk会将输入行拆分为空白字段,因此在选项卡上拆分是多余的。你可以print $1, $2。如果你真的想在操作中看到split函数,请尝试除空白之外的其他内容:

awk '{split($1, a, "0"); print a[1], a[2];}' < input
1 1
1 2
1 3

答案 1 :(得分:1)

分割功能的工作原理如下:

$ cat file
RequestID       CustomerID      Status
101     101111  Error
102     323232  Success
103     33433   Error

$ awk '{split($0,a,"\t"); print a[1],a[2]}' file
RequestID CustomerID
101 101111
102 323232
103 33433

函数需要字符串(在您的情况下应该是您的整行,即$0)后跟数组名称,在这种情况下{{1 }}。最后是分隔符,默认情况下,如果没有提供空格(在您的情况下为a)。

答案 2 :(得分:1)

split需要3个参数:

  1. 必需:要拆分的字符串
  2. 必需:用于分割原始字符串
  3. 所产生的子字符串填充的数组
  4. 可选:分割字符串时使用的正则表达式,FS如果不存在。
  5. 鉴于您的代码应该是显而易见的:

    awk '{split($0,a,/\t/); print a[1], a[2]}' data
    

    请注意,第三个arg to split()是一个RE,所以你不应该做其中任何一个建议elsethread:

    awk '{split($0,a,"\t")...
    awk '{split($0,a,FS)...
    

    "\t"是错误的,因为这是一个常量字符串而不是常量RE(/\t/),因此需要awk将其解析两次,这会在转义字符时导致复杂化。

    FS错误,因为这只是冗余地指定了您从split($0,a)获得的默认值。

答案 3 :(得分:0)

在awk中

,默认字段分隔符是空格,这里是whitespace定义:

Fields are normally separated by whitespace sequences (spaces, TABs, and newlines), not by single spaces.

因此,在您的代码中,当您使用$ 1和$ 2时,您已经使用默认字段分隔符(空格)拆分了该行。如果你需要尝试分割功能,你需要定位在$ 0(整行),其他人提供解决方案,我不需要再写。

在您的情况下,在分割函数中使用FS作为fieldsep,因此您无需关心是否有空格,多个空格,制表符或其他混合空格,例如:

awk '{split($0,a,FS); print a[1],a[2]}' file