bash合并文件中的行

时间:2013-01-23 15:35:56

标签: linux bash shell sed awk

我想转换这段文字:

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)

6 个答案:

答案 0 :(得分:3)

我对sed一无所知,但在AWK中:

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

更新

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

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

答案 1 :(得分:3)

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

$ 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)之后将保留空间的内容附加到模式空间;然后它将行拆分为“换行符之前的所有内容”和“换行符之后的所有内容”,然后切换它们以便'after'(\2)首先出现,然后是空格,然后是'before'( \1)。

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

答案 2 :(得分:2)

这可能适合你(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中保存不包含%的行来处理多个服务器。

答案 3 :(得分:0)

试试这个:

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

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

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

答案 4 :(得分:0)

awk '{if($0~/mysite.com/){x=$0}else{print x,$0}}' your_file

测试here

答案 5 :(得分:0)

使用awk的另一种方法如下:

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

  1. a = $0将该行复制为包含mysite.com
  2. 的行
  3. 如果第二行包含/dev,则它会加入两行
  4. 或其他的potong sed

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