Awk 使用多个分隔符筛选字段

Awk 使用多个分隔符筛选字段,awk,Awk,我已经为解决方案做了大量的搜索,但没有找到我需要的。有这样一个文件: aaa|bbb|ccc|ddd~eee^fff^ggg|hhh|iii 111|222|333|444~555^666^777|888|999 AAA|BBB|CCC||EEE|FFF 我要做的是使用awk或其他方法从该文件返回行,并更改为字段4(以管道分隔)。字段4有一个波浪号和插入符号作为分隔符,这就是我正在努力的地方。我们希望返回的行如下所示: aaa|bbb|ccc|eee|hhh|iii 111|222|33

我已经为解决方案做了大量的搜索,但没有找到我需要的。有这样一个文件:

aaa|bbb|ccc|ddd~eee^fff^ggg|hhh|iii

111|222|333|444~555^666^777|888|999

AAA|BBB|CCC||EEE|FFF
我要做的是使用awk或其他方法从该文件返回行,并更改为字段4(以管道分隔)。字段4有一个波浪号和插入符号作为分隔符,这就是我正在努力的地方。我们希望返回的行如下所示:

aaa|bbb|ccc|eee|hhh|iii

111|222|333|555|888|999

AAA|BBB|CCC||EEE|FFF
如果字段4为空,则按原样返回。但是,当字段4有多个值时,我们只希望在tilde返回后的第一个值

$ awk -F'|' '{sub(/^[^~]*~/, "", $4); sub(/\^.*/, "", $4)} 1' OFS='|' file
aaa|bbb|ccc|eee|hhh|iii
111|222|333|555|888|999
AAA|BBB|CCC||EEE|FFF
这种方法不假设字段4以外的字段的内容。例如,其他字段可能包含
~
^
字符,这些字符不会影响结果

工作原理
  • -F'|'

    这会将输入时的字段分隔符设置为
    |

  • sub(/^[^~]*~/,“”,$4)

    如果字段4包含
    ~
    ,则会删除第一个
    ~
    以及第一个
    ~
    之前的所有内容

  • sub(/\ ^.*/,“”,$4)

    如果字段4包含
    ^
    ,则会删除第一个
    ^
    及其后的所有内容

  • 1

    这是awk对打印行的神秘速记

  • OFS='|'

    这会将输出上的字段分隔符设置为
    |

使用正则表达式作为分隔符
计算字段以决定要执行的操作

将输出分隔符设置为管道

谢谢!我印象深刻!感谢您的快速响应。这两个似乎都是我想要的。谢谢你的解释,也谢谢你对我的理解。@tw84不客气。请注意,如果字段4以外的任何字段包含
~
^
,这两种方法可能会给出不同的答案。约翰,这一点很好。实际上,可能还有其他字段中有^或~,但我试图简化。在这种情况下,您的解决方案似乎仍然有效。
 awk -F "[|^~]" 'BEGIN{OFS="|"}NF==6{print} NF==9{print $1,$2,$3,$5,$8,$9}' tmp.txt 

aaa|bbb|ccc|eee|hhh|iii
111|222|333|555|888|999
AAA|BBB|CCC||EEE|FFF