如何grep和执行命令(针对每个匹配)

如何grep和执行命令(针对每个匹配),grep,Grep,如何在一个文件中grep并为每个匹配执行一个命令 文件: 我想执行,例如,对foo上的每个匹配执行date 以下尝试不起作用: grep file foo | date %s.%N 怎么做 grep file foo | while read line ; do echo "$line" | date %s.%N ; done 在脚本中更容易理解: grep file foo | while read line do echo "$line" | date %s.%N done 对

如何在一个文件中grep并为每个匹配执行一个命令

文件:

我想执行,例如,对
foo
上的每个匹配执行
date

以下尝试不起作用:

grep file foo | date %s.%N
怎么做

grep file foo | while read line ; do echo "$line" | date %s.%N ; done
在脚本中更容易理解:

grep file foo | while read line
do
    echo "$line" | date %s.%N
done
对于每一行输入,
read
将把值放入变量
$line
,而
while
语句将执行
do
done
之间的循环体。由于该值现在在一个变量中,而不是stdin,所以我使用了
echo
将其推回stdin,但您可以只执行
date%s.%N“$line”
,假设date是这样工作的

避免对“grep file foo”中的行使用类似的
,因为
for
总是在空格处中断,这会成为读取文件列表的噩梦:

 find . -iname "*blah*.dat" | while read filename; do ....

如果使用
for

会失败,您真正需要的是xargs命令

在Cygwin环境中匹配某些文件并将匹配项转换为完整windows路径的示例

$ find $(pwd) -type f -exec ls -1 {} \; | grep '\(_en\|_es\|_zh\)\.\(path\)$' | xargs cygpath -w
grep可能需要
--line buffered
选项在匹配匹配行时发出每个匹配行,否则在打印匹配行之前会缓冲多达4K字节,这与此处的目标不符,例如

tail -f source | grep --line-buffered "expression | xargs ...

linux中有一个有趣的命令:
xargs
,它允许您使用前一个命令(grep、ls、find等)的输出作为自定义执行的输入,但有几个选项允许您并行执行自定义命令。以下是一些例子:

for i in `grep "foo" test.txt`; do date +%s.%N; done
for i in `grep "foo" test.txt`; do touch ${i}; done
for i in `grep "foo" test.txt`; do touch "${i}`date +%s.%N`"; done
for i in `grep "foo" test.txt`; do cp ${i} "${i}.backup2"; done
for i in `grep "foo" test.txt`; do cp ${i} "${i}.backup2`date +%s.%N`"; done
根据您的问题,以下是如何在file.txt中为每个“foo”匹配项打印格式为“%s.%N”的日期:

grep "foo" file.txt | xargs -I {} date +%s.%N
更有趣的用法是为每个匹配项创建一个文件,但在这种情况下,如果匹配项相同,则文件将被覆盖:

grep "foo" file.txt | xargs -I {} touch {}
如果要将自定义日期连接到创建的文件

grep "foo" file.txt | xargs -I {} touch "{}`date +%s.%N`"
假设匹配项是文件名,您希望对其进行备份:

grep "foo" file.txt | xargs -I {} cp {} "{}.backup"
最后,对于xargs,在backupName中使用自定义日期

grep "foo" file.txt | xargs -I {} cp {} "{}`date +%s.%N`"
有关并行执行xargs等选项的更多信息,请访问:日期格式:

Extra我发现一个普通的for命令在这种情况下也很有用,它更简单,但通用性较差,下面的命令与上面的示例相同:

for i in `grep "foo" test.txt`; do date +%s.%N; done
for i in `grep "foo" test.txt`; do touch ${i}; done
for i in `grep "foo" test.txt`; do touch "${i}`date +%s.%N`"; done
for i in `grep "foo" test.txt`; do cp ${i} "${i}.backup2"; done
for i in `grep "foo" test.txt`; do cp ${i} "${i}.backup2`date +%s.%N`"; done

玩得开心

没问题。大多数批量任务都有unix工具,包括grep从文件(-f)读取多个模式的能力,或者xargs从stdin构造命令的能力。这应该是:grep foo file------NAME grep,egrep,fgrep,rgrep-打印与模式概要匹配的行grep[OPTIONS]pattern[file…]如何执行脚本:grep file foo |同时读取行do echo“$line”|日期%s.%N完成需要放入文件吗?@EsNoguera如果需要,可以。您可以在命令行上运行它,方法是放置
行间,如读取行时的
grep file foo |;不回显“$line”|日期%s.%N;完成
。要从文件中运行任何命令(包括该命令),只需放入
#/bin/bash
在文件的顶部(我会运行
哪个bash
来找出你的bash住在哪里),粘贴命令,保存它并将它标记为可执行文件:
chmod+x
。要立即执行匹配,在读取行的同时执行
/test.sh | tee/dev/tty | stdbuf-o0 egrep'(foo | bar)|;不回显“找到$line”;完成
grep "foo" file.txt | xargs -I {} cp {} "{}.backup"
grep "foo" file.txt | xargs -I {} cp {} "{}`date +%s.%N`"
for i in `grep "foo" test.txt`; do date +%s.%N; done
for i in `grep "foo" test.txt`; do touch ${i}; done
for i in `grep "foo" test.txt`; do touch "${i}`date +%s.%N`"; done
for i in `grep "foo" test.txt`; do cp ${i} "${i}.backup2"; done
for i in `grep "foo" test.txt`; do cp ${i} "${i}.backup2`date +%s.%N`"; done