使用AWK使用多字符字段分隔符

时间:2013-08-13 06:15:32

标签: awk

我遇到了AWK的字段分隔符问题, 输入文件如下所示

  

1 |所有| |同义词|
  1 |根| |学名|
  2 |细菌|细菌|学名|
  2 | Monera | Monera |部分|
  2 | Procaryotae | Procaryotae |部分|
  2 |原核生物|原核生物|部分|
  2 |原核生物|原核生物|部分|
  2 |细菌|细菌|爆炸名称|

这里的字段分隔符是tab,pipe,tab \t|\t 所以我试图只打印第1和第2列

awk -F'\t|\t' '{print $1 "\t" $2}' nodes.dmp | less

而不是所需的输出,输出是第1列,后跟管道字符。我尝试转义管道\t\|\t,但输出保持不变。

  

1 |
  1 |
  2 |
  2 |
  2 |
  2 |

打印第1列和第3列给了我原始的预期输出。

awk -F'\t|\t' '{print $1 "\t" $3}' nodes.dmp | less

但我很困惑为什么这不按预期工作。

据我所知,下面的perl one liner可以正常工作,但我真正想要的是使用awk。

perl -aln -F"\t\|\t" -e 'print $F[0],"\t",$F[1]' nodes.dmp | less

3 个答案:

答案 0 :(得分:6)

|字符似乎让awk感到困惑,认为\t|\t暗示字段分隔符可能是{em>一个 \t\t。告诉awk从字面上解释|

$ awk -F'\t[|]\t' '{print $1 "\t" $2}'
1   all
1   root
2   Bacteria
2   Monera
2   Procaryotae
2   Prokaryota
2   Prokaryotae
2   bacteria

答案 1 :(得分:1)

来自您发布的输入:

  1. 您的行可以|结尾,而不是|\t
  2. 您有输入包含|\t|
  3. 的案例(前2行)
  4. 您的行以标签
  5. 开头

    因此,tab-pipe-tab的FS是错误的,因为它不会与上述任何情况相匹配,因为第一个只是tab-pipe而第二个中间的tab将匹配tab-pipe-来自前一个字段的选项卡,但随后只留下以下字段的管道标签,第一个字段会留下不合需要的前导标签。

    您实际需要的是将FS设置为tab-pipe,然后从每个字段中删除前导标签:

    awk -F'\t|' -v OFS='\t' '{gsub(/(^|[|])\t/,""); print $1, $2}' file
    

    这样你就可以处理从1到NF-1的所有字段,彼此完全相同。

答案 2 :(得分:0)

使用cut命令:

 cut -f1,2 -d'|' file.txt 

输出中没有pipe

 cut -f1,2 -d'|' file.txt | tr -d '|'