Linux bash合并文件中的行
我要转换此文本:Linux bash合并文件中的行,linux,bash,shell,sed,awk,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-o
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
awk '!/^\/dev/{header=$0;next} {print header, $0}' input.txt
我用过
cat FILE |sed 'N;s/.com\n//'
有没有办法做到这一点,或者我应该写下如果。。。然后
谢谢大家的回答:D(你总是给我看新东西:D)我对sed不太了解,但在AWK:
awk 'NR==1{prefix=$0;next} {print prefix, $0}' file
更新
如果是这种情况,请查找只有一个字段(列)的行,并将其用作前缀。这意味着,对上述脚本的唯一更改是NF(字段数),而不是NR(记录数或行数)
这可能适用于您(GNU-sed):
保存保留空间(HS)中的第一行,然后删除模式空间(PS)1{h;d}
在所有后续行上,将换行符和HS附加到PSG
重新排列PS并删除引入的换行符s/(.*)\n(.*)/\2\1/
sed -r '/%/!{h;d};G;s/(.*)\n(.*)/\2 \1/' file
这将通过在HS中保存不包含%
的行来处理多台服务器。请尝试以下操作:
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
awk '!/^\/dev/{header=$0;next} {print header, $0}' input.txt
或者(功能相同,但更易于阅读和理解,IMO):
测试所用的几乎正确;它只处理一台服务器,而不是多台服务器,但所需的更改很小
$ 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
)先出现,然后是空格,然后是“之前”(\1
)
这使用了经典的
sed
正则表达式;它在Mac OS X(10.7.5)上用BSDsed
和GNUsed
进行了测试,没有任何变化。GNUsed
具有诸如-r
之类的选项来更改正则表达式的解释,这将为您节省一些反斜杠。使用awk的另一种方法如下:
awk'{if($1~/mysite.com/){a=$0}if($1~/dev/){print a”“$0}}”temp.txt
a=$0
如果包含mysite.com
/dev
,则它将连接这两行sed-re'/mysite.com/{h;d};Gs/(.*)\n(.*)/\2\1/'temp.txt
,我想这是值得解释的。我必须用RTFM来解码它在做什么,但是为了一个可升级的答案,我不需要RTFM。很抱歉我编辑了我的问题,你的awk代码工作得很好,但我不知道我需要检查多少服务器…(很抱歉问了两次…)awk应该可以与不同的服务器一起工作;如果只有一列数据,它会保留服务器名称的记录;否则,它将打印最后一个服务器名和当前行。这是可以的,但它恰好是每N次打印一列。所以它产生了第三行:qa-ops01.mysite.com qa-ops02.mysite.com
Gotcha;我把NR误读为NF;将NR更改为NF修复了脚本!回答得很好,不是塞德,但AWK肯定会给你一拳。谢谢你的解释!我正试图拼凑出他的答案是如何运作的,而你正是我想要的。谢谢谢谢我在评论了他的观点后得出了我的答案,但完全是独立的。当我查看我的解决方案和他的解决方案时,我意识到它们几乎相同,除了用于标识服务器行的1
vs regex,以及标准\(.*)
vs GNU(.*)
捕获符号。所以,我在写答案的时候注意到了这一点。(哦,Macsed
需要在d
后面加分号;GNUsed
没有那么麻烦。)非常感谢!现在我将再次进行RTFM,直到我进入我的大脑:D,但这个答案为今天救了我:DHiya,这可能是一个很好的解决方案,也可能不是一个很好的解决方案-但对你的正则表达式进行解释总是很好的,这样其他人就可以跟着你做。不要忘记,全新的程序员使用S/O作为参考,并学习如何做事情。很高兴给他们一个解释,这样他们就可以学习了。我已经添加了解释
awk '{if($0~/mysite.com/){x=$0}else{print x,$0}}' your_file
$ 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
$