将多行输出转换为单行
我管理着一个拥有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