Answers:
就是xargs
那样
... | xargs command
接受的答案具有正确的想法,但关键是要通过xargs
的-n1
开关,这意味着“每输出的线一旦执行命令:”
cat file... | xargs -n1 command
或者,对于单个输入文件,您可以cat
完全避免使用管道,而只需执行以下操作:
<file xargs -n1 command
xargs
,以不运行,如果stdin
是空的: --no-run-if-empty
-r
:如果标准输入不包含任何非空白,不运行命令。通常,即使没有输入,命令也会运行一次。此选项是GNU扩展。
command
?
在Bash或任何其他Bourne风格的shell(ash,ksh,zsh等)中:
while read -r line; do command "$line"; done
read -r
从标准输入中读取一行(read
不-r
解释反斜线,则不需要这样做)。因此,您可以执行以下任一操作:
$ command | while read -r line; do command "$line"; done
$ while read -r line; do command "$line"; done <file
tail -f syslog | grep -e something -e somethingelse| while read line; do echo $line; done
时不起作用。它使用通过管道传递到while
循环中的文件,仅使用tail -f
,使用just grep
,但不适用于两个管道。给出grep
的--line-buffered
选项使它的工作
command | while read -r line; do echo "$line" | command ; done
我同意Keith的观点,xargs是最通用的工具。
我通常使用3个步骤。
有更小更快的方法,但是这种方法几乎总是可行的。
一个简单的例子:
ls |
grep xls |
awk '{print "MyJavaProg --arg1 42 --arg2 "$1"\0"}' |
xargs -0 bash -c
前两行选择了一些要使用的文件,然后awk用一个要执行的命令和一些参数准备了一个不错的字符串,$ 1是管道的第一列输入。最后,我确保xargs将此字符串发送给刚执行的bash。
这有点矫over过正,但是由于它非常灵活,因此在很多地方对我都有帮助。
xargs -0
使用空字节作为记录分隔符,因此您的awk打印语句应为printf("MyJavaProg --args \"%s\"\0",$1)
awk
,可以让它进行模式匹配并跳过grep
例如,ls | awk '/xls/ {print...
GNU Parallel专为此类任务而设计。最简单的用法是:
cat stuff | grep pattern | parallel java MyProg
观看介绍性视频以了解更多信息:http : //www.youtube.com/watch?v=OpaiGYxkSuQ
cat
这里没有真正的需要,因为grep
可以直接读取文件
< stuff grep pattern
但是根本grep pattern stuff
不需要重定向或cat。不过,这并不会从根本上改变您的论点,如果您认为始终在以开头的管道中使用东西是cat
另外,while read
在鱼壳中循环(考虑到您使用的是鱼标签,我假设您需要鱼壳)。
command | while read line
command $line
end
需要注意的几点。
read
-r
为了使最常见的用例变得容易,不接受参数,也不解释反斜杠。$line
,就像bash一样,fish不会用空格分隔变量。command
本身就是语法错误(以捕获占位符参数的这种用法)。用real命令替换它。while
需要与配对do
&done
代替end
?
如果需要控制将输入参数确切地插入命令行的位置,或者需要重复几次,则需要使用xargs -I{}
。
在其中创建一个空文件夹结构,another_folder
以镜像当前目录中的子文件夹:
ls -1d ./*/ | xargs -I{} mkdir another_folder/{}
例子#2
对来自stdin的文件列表进行操作,在这种情况下,.html
通过添加.bak
扩展名来复制每个文件:
find . -iname "*.html" | xargs -I{} cp {} {}.bak
-I replstr
Execute utility for each input line, replacing one or more occurrences of
replstr in up to replacements (or 5 if no -R flag is specified) arguments
to utility with the entire line of input. The resulting arguments, after
replacement is done, will not be allowed to grow beyond 255 bytes; this is
implemented by concatenating as much of the argument containing replstr as
possible, to the constructed arguments to utility, up to 255 bytes. The
255 byte limit does not apply to arguments to utility which do not contain
replstr, and furthermore, no replacement will be done on utility itself.
Implies -x.
Linux xargs
手册页:
-I replace-str
Replace occurrences of replace-str in the initial-
arguments with names read from standard input. Al‐
so, unquoted blanks do not terminate input items;
instead the separator is the newline character.
Implies -x and -L 1.
在处理潜在的未经过滤的输入时,我希望在运行它之前逐行查看整个作业的“拼写”以进行视觉检查(尤其是在破坏性工作,例如清理人们的邮箱时)。
所以我要做的是生成一个参数列表(即用户名),以每行一个记录的方式将其馈送到文件中,如下所示:
johndoe
jamessmith
janebrown
然后,我在中打开列表vim
,并使用搜索和替换表达式对其进行处理,直到获得需要执行的完整命令的列表,如下所示:
/bin/rm -fr /home/johndoe
/bin/rm -fr /home/jamessmith
这样,如果您的正则表达式不完整,您将看到在哪个命令中有潜在的问题(即/bin/rm -fr johnnyo connor
)。这样,您可以撤消正则表达式,然后使用更可靠的版本再次尝试。改名是为此而臭名昭著的,因为很难处理像梵高,奥康纳斯,圣克莱尔,史密斯-韦森这样的边缘案件。
在set hlsearch
中,对于具有此功能很有用vim
,因为它会突出显示所有匹配项,因此您可以轻松地发现匹配项是否不匹配或以非预期方式匹配。
一旦您的正则表达式是完美的并捕获了您可以测试/考虑的所有情况,那么我通常将其转换为sed表达式,以便可以完全自动化以进行另一次运行。
对于输入行数妨碍您进行外观检查的情况,我强烈建议在执行命令之前将命令回显到屏幕(或者更好的是日志),因此,如果出现错误,您可以确切地知道引起该命令的原因它失败了。然后,您可以返回到原始正则表达式并再次进行调整。
我更喜欢-允许多行命令和清除代码
find -type f -name filenam-pattern* | while read -r F
do
echo $F
cat $F | grep 'some text'
done
printf "foo bar\nbaz bat" | xargs echo whee
将屈服whee foo bar baz bat
。也许添加-L
或-n
选项?