我管理着一台装有40台ubuntu机器的计算机实验室,我拼凑了这个命令,找到学生主目录中大于100M的文件的总磁盘使用量:
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文件中的输出包含每个机器的类似内容(我在括号中插入了注释):
69G total
hostname
student-username (changes)
admin-username (always the same)
lost+found (always the same)
我希望每台机器的输出看起来像这样:
69G主机名学生用户名
我对文本过滤不够熟悉,无法及时完成。你能帮忙吗?
答案 0 :(得分:1)
试试这个:
awk -vORS=" " 'NR==1{sub("total","")}NR<=3' file
答案 1 :(得分:1)
我稍微修改了您的示例数据:
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
)来确定每组五行中的位置。
如果您不能依赖每组五行,那么请说明您的输入数据的结构。我们可以通过其他方式检测记录边界,例如查找/[0-9]+G total$/
,如果无法使用NR%5
:
[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):
[ghoti@pc ~/tmp]$ sed -ne '/G total/{s/ .*//;N;N;s/\n/ /g;p;}' lab-disk-usage.txt
69G host1 jane
65G host2 albert
答案 2 :(得分:1)
tr
命令您可以尝试更简单的解决方案,例如通过 tr 命令管道输出。例如:
tr -s "\n" ' ' < lab-disk-usage.txt
这假设文件中只有一条记录。如果您计划拥有多条记录,则需要先将每条记录通过 tr 管道过滤,然后再将其附加到输出文件中。例如:
your_pipeline_commands | tr -s "\n" ' ' > lab-disk-usage.txt
如果您有一组多行记录,则需要更加聪明。与AWK相比,Perl在处理多线记录方面具有一些优势,包括触发器操作器。例如:
perl -ne 'if ( /total/../^lost/ ) {
chomp $_; print $_ . " "
} else {
print "\n"
};
END { print "\n" };' lab-disk-usage.txt
根据您的实际语料库,您可能需要稍微调整一下正则表达式才能使事情正常运行,但在我的系统上它做的是正确的。
69G total
hostname
student-username
admin-username
lost+found
69G total
hostname
student-username
admin-username
lost+found
69G total hostname student-username admin-username lost+found
69G total hostname student-username admin-username lost+found
答案 3 :(得分:0)
这可能适合你(GNU sed):
sed -nr '/ total/{N;N;s/( total\s*)?\n/ /gp}' file
答案 4 :(得分:0)
如果记录之间没有空行,您可以先引入一行:
awk '/total/{print x}1' | awk '{print $1,$3,$4}' RS= OFS='\t'
使用文件内容:
69G total
host1
jane
admin-username
lost+found
65G total
host2
albert
admin-username
lost+found
这会产生:
69G host1 jane
65G host2 albert
如果记录之间已经有空行,您可以在管道之前跳过该部分并使用:
awk '{print $1,$3,$4}' RS= OFS='\t' file