Shell命令循环遍历行?

时间:2009-07-01 00:31:40

标签: command-line

最近,我经常发现自己想要在另外几个输出的命令的输出上运行一些命令。

例如,假设我有一个命令在新行上返回多个文件路径,我想删除所有这些文件。

是否有可以帮助我这样做的命令?

6 个答案:

答案 0 :(得分:6)

听起来你正在寻找xargs。从手册页:

  

xargs从标准输入读取参数,由空格分隔(可以使用双引号或单引号或反斜杠保护)或换行符,并使用任何初始值执行命令(默认为/ bin / echo)一次或多次-arguments后跟从标准输入读取的参数。

所以你可以这样做:

ls | grep -v '*.cpp' | xargs rm

上述命令将删除当前目录中除*.cpp个文件以外的所有内容。

答案 1 :(得分:3)

在类似bash的shell中你可以这样做:

rm `your command`

rm $(your command)

答案 2 :(得分:3)

在Windows中,CMD:

for /f "usebackq delims=" %i in (`your command`) @del "%i"

Powershell的:

your command | Remove-Item

答案 3 :(得分:1)

ls | xargs rm

一个有趣的用途(在目录中搜索文件中的短语)

find /path/to/dir | xargs grep "search text"

那个没有关系,但它显示了xargs如何工作

答案 4 :(得分:1)

假设类似UNIX的环境:

要处理名称中的空格,请使用-0标志来表示xargs。找到:

find . -name '*.mp3' -print0 | xargs -0 dosomething

其他一些命令有多个用于nul分隔输出的开关,通常为-0-z。如果您的列表是面向行的,请执行以下操作:

cat filelist | tr -s '\012\015' '\000' | xargs -0 dosomething

使用tr将换行符和换行符转换为nuls,处理UNIX和DOS(甚至Mac Classic)行结束并跳过空白行。

不要忘记新行是大多数类UNIX文件系统上的有效文件名字符。

如果dosomething很复杂,您可以使用bash函数:

dosomething() {
    while [ -n "$1" ] ; do
        out="$(basename "$1" .mp3).ogg"
        convert "$1" "converted/$out"
        shift
    done
}

export -f dosomething

并调用xargs,如:

cat filelist | tr -s '\012\015' '\000' | xargs -0 bash -c 'dosomething "$@"' --

请注意明智地使用双引号来保留空格,并且双引号字符串可以嵌套在双引号$() eval运算符中。

在函数中,您可以编写"$@"以获取正确引用的参数列表以传递给子流程:

dosomething() {
    command1 preargs "$@" postargs | command2
    command3 "$@"
}

您还可以使用read逐行工作:

cat filelist | while read i ; do something "$i" ; done

但是xargs会立刻获得所有的args。

答案 5 :(得分:0)

cat file | while read i; do echo "working on line $i"; done

虽然您可能遇到有空格的线路问题。我永远不会记得如何解决这个问题。 请注意,此命令适用于逐行的每个操作。使用xargs仅适用于您提出的示例案例(以及类似案例),但如果您可以使用xargs解决问题,请务必使用它。