将多行输出转换为单行

将多行输出转换为单行

问题描述:

我管理着一个拥有40台ubuntu机器的计算机实验室,并且我已经拼凑了这个命令,以查找学生主目录中大于100M的文件的磁盘总使用量:

I manage a computer lab with 40 ubuntu machines and I have cobbled together this command to find the total disk usage of files larger than 100M in the students' home directories:

for i in `cat ./lab-machines.txt ` ; do ssh $i "nohup find /home -size +100M -print0 | du --files0-from=- -ch | tail -1 && hostname && ls /home" ; done > lab-disk-usage.txt

文件"lab-machines.txt"在每行中分别包含计算机的主机名.该命令从已配置了无密码登录名的服务器运行到root用户的实验室计算机中.每台机器的文件lab-disk-usage.txt中的输出都包含以下内容(我在括号中插入了注释):

The file "lab-machines.txt" contains the hostnames of the computers on a separate line each. The command runs from a server that has been configured with password-less logins into the lab machines for the root user. The output in the file lab-disk-usage.txt contains something like this for every machine (I've inserted comments in parenthesis):

69G total    
hostname
student-username (changes)
admin-username (always the same)
lost+found (always the same)

我希望每台机器的输出看起来像这样:

I would like the output to look like this for each machine:

69G主机名学生用户名

69G hostname student-username

我对文本过滤不够熟悉,无法及时完成此操作.你能帮忙吗?

I am not familiar enough with text filtering to get this done in time. Can you help?

我对您的示例数据做了一些修改:

I've slightly modified your example data:

69G total    
host1
jane
admin-username
lost+found
65G total    
host2
albert
admin-username
lost+found

这可以变成一张桌子:

[ghoti@pc ~/tmp]$ awk 'NR%5==1{size=$1} NR%5==2{host=$1} NR%5==3{user=$1; printf("%-8s%-16s%s\n", size, host, user)}' lab-disk-usage.txt
69G     host1           jane
65G     host2           albert

她的基本要点是,我们正在使用模运算符(NR%5)来确定每行五行中的位置.

The essential thing her is that we're using a modulo operator (NR%5) to figure out where we are in each set of five lines.

如果您不能依靠每组五行,请说明输入数据的结构.如果无法使用NR%5,我们还有其他方法可以检测记录边界,例如寻找/[0-9]+G total$/:

If you can't rely on five lines per set, then please clarify how your input data is structured. There are other ways we can detect record boundaries, like looking for /[0-9]+G total$/, if NR%5 can't be used:

[ghoti@pc ~/tmp]$ awk '/G total$/{size=$1; getline host; getline user; printf("%-8s%-16s%s\n", size, host, user)}' lab-disk-usage.txt 
69G     host1           jane
65G     host2           albert

这基本上只是potong的 GNU sed 建议的awk版本,也可以将其移植为便携式(即不仅是GNU sed),如下所示:

This is basically just an awk version of potong's GNU sed suggestion, which could also be made portable (i.e. not just GNU sed) as:

[ghoti@pc ~/tmp]$ sed -ne '/G total/{s/ .*//;N;N;s/\n/  /g;p;}' lab-disk-usage.txt 
69G  host1  jane
65G  host2  albert