我下面有两个 for 循环,它们创建最终输出作为排序文件,但我只想合并到一个 for 循环中
for i in *.txt; do
cut -f 5,10 $i >$i.txt.out
done
###sorting
for i in *.txt.out; do
sort -k1,1 $i >$i.sort
done
我尝试通过使用管道重定向第一个 for 循环的输出,将两个循环合并为一个循环。我尝试了这篇文章中的一种方法(将上一个命令的输出作为参数传递给下一个命令)但无法得到想要的结果。
for i in *.txt; do
cut -f 5,10 $i >$i.txt.out | xargs -I{} sort -k1,1 {} >$i.sort
done
有什么建议么?
谢谢
罗恩
答案1
for name in *.txt; do
cut -f 5,10 -- "$name" | sort -k 1,1 >"$name.sort"
done
这将结合两个初始循环的效果,同时消除中间文件的使用。
我做了一些小修改:
- 引用所有变量的展开式,因为什么时候需要双引号?
- 为循环变量使用更好的名称。
- 如果文件名以破折号开头,则将变量与
cut
命令分隔开--
来表示选项结束。$name
还可以使用它sort -k 1,1 -o "$name.sort"
来代替sort
上面的命令,让sort
实用程序创建输出文件而不是 shell(细微差别)。
该xargs
实用程序经常使用代替一个循环:
printf '%s\n' *.txt | xargs -I {} sh -c 'cut -f 5,10 -- "$1" | sort -k 1,1 >"$1.sort"' sh "{}"
...但在这里它只会让事情变得更加复杂(上面的命令在处理包含换行符的文件名时会出现问题)。
你的命令
cut -f 5,10 $i >$i.txt.out | xargs -I{} sort -k1,1 {} >$i.sort
将执行cut
并将输出保存到$i.txt.out
(已$i
扩展)。xargs
由于输出cut
被重定向到文件,该命令将无法获得输入。如果您没有重定向 的输出cut
,xargs
则会sort
使用内容文件的名称作为参数而不是文件名。这不是您想要的(您想要将cut
as的输出传递给数据进入sort
)。