将上一个命令的输出传递到下一个命令

将上一个命令的输出传递到下一个命令

我下面有两个 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被重定向到文件,该命令将无法获得输入。如果您没有重定向 的输出cutxargs则会sort使用内容文件的名称作为参数而不是文件名。这不是您想要的(您想要将cutas的输出传递给数据进入sort)。

相关内容