【问题标题】:UNIX: recursively paste a substring into the same string in unixUNIX:递归地将子字符串粘贴到 unix 中的同一字符串中
【发布时间】:2014-10-28 11:15:07
【问题描述】:

我的文件如下:

$ cat a 
Server1 - free space: / 60% : /opt 40%: /var 50%    
Server2 - free space: / 50% : /opt 30%: /var 60%    
Server3 - free space: / 30% : /opt 50%: /var 40%

输出将被写入另一个文件 b.我的预期输出如下:

$ cat b
Server1 - free space: / 60% 
Server1 - free space: /opt 40%
Server1 - free space: /var 50%
Server2 - free space: / 50% 
Server2 - free space: /opt 30%
Server2 - free space: /var 60%
Server3 - free space: / 30% 
Server3 - free space: /opt 50%
Server3 - free space: /var 40%

【问题讨论】:

    标签: shell unix awk sed cut


    【解决方案1】:

    对于这种情况,您需要将“主题”文本与数据分开。

    使用 awk 您可以免费获得它,因为它会解析每个输入行,并将每个字段放入编号变量中 - $1、$2 等。 您还可以免费获得每行的实际字段数 - NF,由 awk 计算

    鉴于此,您可以开始

    awk '{ print $1, $2 }' a
    
    Output: Server1 -
    

    不完全是你想要的。

    可以继续手动计数,甚至只是硬编码一些文本:

    awk '{ Subject=$1" "$2" "$3" "$4 ; print Subject, $5, $6, "\n" Subject, $8, $9, "\n" Subject, $10, $11 }' b
    

    虽然,这会打印您的输出,但它不是很优雅。但是,您可以对字段有所了解。

    当 awk 将一行拆分为多个字段时,我通过说一个字段是任何被空格包围的字段来做到这一点,即 , . 您可以通过使用命令行参数“-F”或在 BEGIN 块中显式设置来更改 awk 使用的字段分隔符。

    BEGIN 块在 awk 甚至查看文件之前运行一次

    那么你可以这样做:

    awk 'BEGIN { FS=":" } { print $1, $2 }' a
    
    Output: Server1 - free space  / 60%
    

    所以你越来越近了,但你还想在输出前加一个分号,所以你这样做:

    awk 'BEGIN { FS=":" } { print $1 ":", $2 }' a
    
    # Or, by setting OFS - the Output Field Separator
    awk 'BEGIN { FS=":" ; OFS=":" } { print $1,$2 }' a
    
    Output: Server1 - free space: / 60%
    

    您的输出中仍然只有一个文件系统,因此您也需要引用这些文件系统,如果您确定输入中始终只有三个文件系统,则可以直接完成:

    $ awk 'BEGIN { FS=":" ; OFS=":" } { print $1,$2 "\n" $1, $3 "\n" $1, $4 }' a
    
    Server1 - free space: / 60%
    Server1 - free space: /opt 40%
    Server1 - free space: /var 50%
    

    但是你想要的是一个循环,它让你在遇到的文件系统/字段的数量方面具有灵活性,你可以在哪里得到 Ed Morton 的答案,我刚刚移动了 FS(字段分隔符)和 OFS 的声明(输出字段分隔符)到 BEGIN 块:

    $ awk 'BEGIN { FS=":" ; OFS=":" } {for (i=2;i<=NF;i++) print $1, $i}' a > b
    $ cat b
    Server1 - free space: / 60%
    Server1 - free space: /opt 40%
    Server1 - free space: /var 50%
    Server2 - free space: / 50%
    Server2 - free space: /opt 30%
    Server2 - free space: /var 60%
    Server3 - free space: / 30%
    Server3 - free space: /opt 50%
    Server3 - free space: /var 40%
    

    你还有一个 END 块,它在 所有行都被解析之后运行:

    $ awk 'BEGIN { FS=":" ; OFS=":" }
        {servers++ ; for (i=2;i<=NF;i++) { print $1, $i ; sum++ } }
        END { printf("\nParsed %i lines producing %i lines\n", servers, sum) }' a
    Server1 - free space: / 60%
    Server1 - free space: /opt 40%
    Server1 - free space: /var 50%
    Server2 - free space: / 50%
    Server2 - free space: /opt 30%
    Server2 - free space: /var 60%
    Server3 - free space: / 30%
    Server3 - free space: /opt 50%
    Server3 - free space: /var 40%
    
    Parsed 3 lines producing 9 lines
    

    【讨论】:

      【解决方案2】:
      $ awk -F' *: *' -v OFS=': ' '{for (i=2;i<=NF;i++) print $1, $i}' file 
      Server1 - free space: / 60%
      Server1 - free space: /opt 40%
      Server1 - free space: /var 50%
      Server2 - free space: / 50%
      Server2 - free space: /opt 30%
      Server2 - free space: /var 60%
      Server3 - free space: / 30%
      Server3 - free space: /opt 50%
      Server3 - free space: /var 40%
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-10-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-10-20
        • 2020-01-07
        相关资源
        最近更新 更多