【问题标题】:bash to merge lines in a filebash 合并文件中的行
【发布时间】:2013-01-23 15:35:55
【问题描述】:

我想转换这段文字:

qa-ops01.mysite.com
/dev/mapper/sys-home   58G   26G   30G  47% /home
/dev/mapper/sys-tmp   3.9G  2.3G  1.5G  61% /tmp
qa-ops02.mysite.com
/dev/mapper/sys-home   58G   26G   30G  47% /usr
/dev/mapper/sys-tmp   3.9G  2.3G  1.5G  61% /var
qa-ops03.mysite.com
/dev/mapper/sys-home   58G   26G   30G  47% /lib
/dev/mapper/sys-tmp   3.9G  2.3G  1.5G  61% /etc

到这个:

qa-ops01.mysite.com /dev/mapper/sys-home   58G   26G   30G  47% /home
qa-ops01.mysite.com /dev/mapper/sys-tmp   3.9G  2.3G  1.5G  61% /tmp  
qa-ops02.mysite.com /dev/mapper/sys-home   58G   26G   30G  47% /usr
qa-ops02.mysite.com /dev/mapper/sys-tmp   3.9G  2.3G  1.5G  61% /var   
qa-ops03.mysite.com /dev/mapper/sys-home   58G   26G   30G  47% /lib
qa-ops03.mysite.com /dev/mapper/sys-tmp   3.9G  2.3G  1.5G  61% /etc

我用过

cat FILE |sed 'N;s/.com\n//'

有没有办法实现这一点,或者我应该只写 If...Then...

感谢大家的回答:D(你总是给我展示新事物:D)

【问题讨论】:

    标签: linux bash shell sed awk


    【解决方案1】:

    potonganswer 几乎是正确的;它只处理一台服务器,而不是多台服务器,但所需的更改很小。

    $ sed -e '/^[^ ]*$/{h;d;}' -e 'G; s/\(.*\)\n\(.*\)/\2 \1/' data
    qa-ops01.mysite.com /dev/mapper/sys-home   58G   26G   30G  47% /home
    qa-ops01.mysite.com /dev/mapper/sys-tmp   3.9G  2.3G  1.5G  61% /tmp
    qa-ops02.mysite.com /dev/mapper/sys-home   58G   26G   30G  47% /usr
    qa-ops02.mysite.com /dev/mapper/sys-tmp   3.9G  2.3G  1.5G  61% /var
    qa-ops03.mysite.com /dev/mapper/sys-home   58G   26G   30G  47% /lib
    qa-ops03.mysite.com /dev/mapper/sys-tmp   3.9G  2.3G  1.5G  61% /etc
    $
    

    脚本分为两部分,由两个-e 选项标识。第一部分标识服务器名称;这些行不包含空格(因此/^[^ ]*$/ 查找没有空格的行),并将该行复制到保留空间(h),然后将其删除(d)并继续下一行。脚本的第二部分仅在包含空格的行上执行。它将保持空间的内容附加到换行符之后的模式空间(G);然后它将该行分成“直到换行符的所有内容”和“换行符之后的所有内容”,并切换它们以便“之后”(\2)首先出现,然后是空格,然后是“之前”(@987654330 @)。

    这使用了经典的sed正则表达式;它在 Mac OS X (10.7.5) 上使用 BSD sed 和 GNU sed 进行了测试,没有改变。 GNU sed 具有诸如 -r 之类的选项来更改正则表达式的解释,这将为您节省一些反斜杠。

    【讨论】:

    • 很好的解释!我试图拼凑他的答案是如何工作的,而你正是我想要的。谢谢!
    • 谢谢。在评论了他之后,我制定了我的答案,但完全独立。当我查看我的解决方案和他的解决方案时,我意识到它们几乎相同,除了 1regex 来识别服务器线路,以及标准 \(.*\) 与 GNU (.*)捕获符号。所以,我在写答案文本时注意到了这一点。 (哦,Mac sed 需要在 d 后面加上分号;GNU sed 没那么挑剔。)
    • 非常感谢!现在我将再次去 RTFM,直到我进入我的大脑:D,但这个答案今天救了我:D
    【解决方案2】:

    我对 sed 了解不多,但是在 AWK 中:

    awk 'NR==1{prefix=$0;next} {print prefix, $0}' file
    

    更新

    如果是这种情况,请查找只有一个字段(列)的行,将其用作前缀。这意味着,对上述脚本的唯一更改是 NF(字段数)代替了 NR(记录数或行数)。

    awk 'NF==1{prefix=$0;next} {print prefix, $0}' file
    

    【讨论】:

    • 很抱歉我编辑了我的问题,你的 awk 代码运行良好,但我不知道我需要检查多少台服务器......(抱歉问了两次......)跨度>
    • awk 应该可以在不同的服务器上正常工作;如果只有一列数据,它会记录服务器名称;否则,它会打印最后一个服务器名称和当前行。
    • 没关系,但恰好每N次1列。所以它产生第三行:qa-ops01.mysite.com qa-ops02.mysite.com
    • 明白了;我将 NR 误读为 NF;将 NR 更改为 NF 可修复脚本!
    • 很好的答案,不是 sed,但 AWK 确实很有用。谢谢吴海。
    【解决方案3】:

    这可能对你有用(GNU sed):

    sed -r '1{h;d};G;s/(.*)\n(.*)/\2 \1/' file
    
    • 1{h;d} 将第一行保存在保持空间 (HS) 中,然后删除模式空间 (PS)。
    • G 在所有后续行中附加一个换行符和 HS 到 PS。
    • s/(.*)\n(.*)/\2 \1/重新排列PS,去掉引入的换行符。

    自发布答案后,原始问题已更改,请考虑到这一点:

    sed -r '/%/!{h;d};G;s/(.*)\n(.*)/\2 \1/' file
    

    这通过在 HS 中保存不包含 % 的行来处理多个服务器。

    【讨论】:

    • 我认为这需要一些解释。我必须使用 RTFM 来解码它在做什么,但是为了得到一个可赞成的答案,我不需要 RTFM。
    【解决方案4】:

    试试这个:

    awk '!/^\/dev/{header=$0;next} {print header, $0}' input.txt
    

    或者(功能相同,但更易于阅读和理解,IMO):

    awk '{if($0 !~ /^\/dev/){header=$0}else{print header, $0}}' input.txt
    

    【讨论】:

      【解决方案5】:
      awk '{if($0~/mysite.com/){x=$0}else{print x,$0}}' your_file
      

      测试here

      【讨论】:

        【解决方案6】:

        另外一种使用awk的方式如下:

        awk '{if ($1 ~ /mysite.com/){a= $0 } if ($1 ~ /dev/){ print a" "$0}}' temp.txt

        1. a = $0 将该行复制到包含 mysite.com 的 if
        2. 如果第二行包含/dev,则它会加入两行

        或其他 potong sed 的变体

        sed -re '/mysite.com/{h;d};G;s/(.*)\n(.*)/\2 \1/' temp.txt

        【讨论】:

        • 嗨,这可能是一个好的解决方案,也可能不是一个好的解决方案——但对你的正则表达式进行解释总是好的,这样其他人就可以跟随你正在做的事情。不要忘记,全新的程序员使用 S/O 作为参考并学习如何做事。很高兴给出解释,以便他们学习。
        • 我已经添加了解释
        猜你喜欢
        • 2020-07-04
        • 2019-06-25
        • 1970-01-01
        • 2013-07-23
        • 1970-01-01
        • 2012-11-23
        • 1970-01-01
        • 1970-01-01
        • 2017-09-06
        相关资源
        最近更新 更多