【问题标题】:Print the same columns as a new line cutting after delimiter in awk在 awk 中的分隔符之后打印与新行切割相同的列
【发布时间】:2018-02-14 12:28:42
【问题描述】:

我有一个文件,其内容如下:

1 18997 19003 ABCP@CC;8CYUS|ABCP@CC;8C|ABCP@CC;8C|XXYG;UY|UOO98,|ABCP@CC;8CYUS
2 87737 93837 AASC

因此,有些行的第 4 列带有分隔符,有些则没有。

我想要的是,每当我看到"|" 时剪切,并将前 3 列附加为新行:

1 18997 19003 ABCP@CC;8CYUS
1 18997 19003 ABCP@CC;8C
1 18997 19003 ABCP@CC;8C
1 18997 19003 XXYG;UY
1 18997 19003 UOO98,
1 18997 19003 ABCP@CC;8CYUS
2 87737 93837 AASC

然后我将申请uniq 并删除重复项。 我已经尝试过:

awk '{split($0,a,"|"); print a[1],a[2],a[3],a[4]}' 但是,它只会将第 4 列拆分到同一行中,并且不会将其附加到新行。

我怎样才能得到预期的输出?

【问题讨论】:

    标签: awk delimiter


    【解决方案1】:

    您必须为提取的数组中的每个项目打印一次。当然,只拆分第四个字段。

    awk '{ n = split($4, a, "|"); for (i=1; i<=n; ++i) print $1, $2, $3, a[i] }' file
    

    如果您想确保输出是唯一的,Awk 也可以做到。

    awk '{ n = split($4, a, "|");
        for (i=1; i<=n; ++i) {
            x = $1 OFS $2 OFS $3 OFS a[i]
            if (!seen[x]++) print x } }' file
    

    【讨论】:

    • 但是如果我没有任何分隔符,它会打印“1”
    • 那么您问题中的示例数据不完整。没有分隔符的线是什么样子的?也许在左大括号之前添加/\|/ 作为条件。
    • 是的,我已经编辑过了。抱歉我之前给出的错误示例
    • 为我工作;你复制/粘贴不正确吗?也许重新加载页面,因为我在几分钟前编辑了答案,虽然它在这里不可见(不显示 5 分钟“宽限期”内的编辑)。
    【解决方案2】:

    使用awk

    awk '{ s= $1 FS $2 FS $3; gsub(/\|/,RS s" ") }1' infile
    

    awk -F'[ |]' '{for(i=4; i<=NF; i++)print $1,$2,$3,$i}' infile
    

    输入:

    $ cat infile
    1 18997 19003 ABCP@CC;8CYUS|ABCP@CC;8C|ABCP@CC;8C|XXYG;UY|UOO98,|ABCP@CC;8CYUS
    2 87737 93837 AASC
    

    输出:

    $ awk '{ s= $1 FS $2 FS $3; gsub(/\|/,RS s" ") }1' infile
    1 18997 19003 ABCP@CC;8CYUS
    1 18997 19003 ABCP@CC;8C
    1 18997 19003 ABCP@CC;8C
    1 18997 19003 XXYG;UY
    1 18997 19003 UOO98,
    1 18997 19003 ABCP@CC;8CYUS
    2 87737 93837 AASC
    
    $ awk -F'[ |]' '{for(i=4; i<=NF; i++)print $1,$2,$3,$i}' infile
    1 18997 19003 ABCP@CC;8CYUS
    1 18997 19003 ABCP@CC;8C
    1 18997 19003 ABCP@CC;8C
    1 18997 19003 XXYG;UY
    1 18997 19003 UOO98,
    1 18997 19003 ABCP@CC;8CYUS
    2 87737 93837 AASC
    

    编辑 - 独特

    $ awk -F'[ |]' '{split("",arr);for(i=4; i<=NF; i++){if(!($i in arr))print $1,$2,$3,$i; arr[$i]}}' infile
    1 18997 19003 ABCP@CC;8CYUS
    1 18997 19003 ABCP@CC;8C
    1 18997 19003 XXYG;UY
    1 18997 19003 UOO98,
    2 87737 93837 AASC
    

    【讨论】:

    • 我已经编辑了我的输入,抱歉我之前给的不完整
    • @bapors 你试过了吗??
    • uniq 变体不会捕获来自不同输入行的重复项。根据您的输入约束,这可能是一个错误或一个功能(更好地处理大输入文件,因为它忘记了前几行的内容,即即使您处理数 GB 的数据也不会用完所有内存)。
    • @tripleee 抱歉,我无法及时回复,我认为它在每条记录中都是唯一的,而不是在所有记录中都是唯一的
    • 是的;也许我们永远不会发现。 (-:
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-23
    • 2020-03-29
    • 2018-02-19
    • 2015-02-04
    • 1970-01-01
    相关资源
    最近更新 更多