使用多个命令查找-exec

时间:2011-02-25 16:42:19

标签: bash find

我正在尝试将find -exec与多个命令一起使用而没有任何成功。有人知道以下命令是否可行?

find *.txt -exec echo "$(tail -1 '{}'),$(ls '{}')" \;

基本上,我正在尝试打印当前目录中每个txt文件的最后一行,并在该行的末尾打印,后跟文件名的逗号。

12 个答案:

答案 0 :(得分:552)

find接受命令的多个-exec部分。例如:

find . -name "*.txt" -exec echo {} \; -exec grep banana {} \;

请注意,在这种情况下,第二个命令只会在第一个命令成功返回时运行,如@Caleb所述。如果您希望两个命令都运行而不管它们的成功或失败,您可以使用此构造:

find . -name "*.txt" \( -exec echo {} \; -o -exec true \; \) -exec grep banana {} \;

答案 1 :(得分:79)

find . -type d -exec sh -c "echo -n {}; echo -n ' x '; echo {}" \;

答案 2 :(得分:47)

以下其中一项:

find *.txt -exec awk 'END {print $0 "," FILENAME}' {} \;

find *.txt -exec sh -c 'echo "$(tail -n 1 "$1"),$1"' _ {} \;

find *.txt -exec sh -c 'echo "$(sed -n "\$p" "$1"),$1"' _ {} \;

答案 3 :(得分:14)

另一种方式是这样的:

multiple_cmd() { 
    tail -n1 $1; 
    ls $1 
}; 
export -f multiple_cmd; 
find *.txt -exec bash -c 'multiple_cmd "$0"' {} \;

在一行

multiple_cmd() { tail -1 $1; ls $1 }; export -f multiple_cmd; find *.txt -exec bash -c 'multiple_cmd "$0"' {} \;
  • multiple_cmd()” - 是一个功能
  • export -f multiple_cmd” - 将导出它,以便任何其他子shell可以看到它
  • find *.txt -exec bash -c 'multiple_cmd "$0"' {} \;” - 找到将执行示例
  • 的功能

通过这种方式,multiple_cmd可以根据需要同样长且复杂。

希望这有帮助。

答案 4 :(得分:8)

有一种更简单的方法:

find ... | while read -r file; do
    echo "look at my $file, my $file is amazing";
done

可替换地:

while read -r file; do
    echo "look at my $file, my $file is amazing";
done <<< "$(find ...)"

答案 5 :(得分:7)

我不知道你是否可以使用find来做到这一点,但另一种解决方案是创建一个shell脚本并使用find运行它。

lastline.sh:

echo $(tail -1 $1),$1

使脚本可执行

chmod +x lastline.sh

使用find

find . -name "*.txt" -exec ./lastline.sh {} \;

答案 6 :(得分:4)

丹尼斯的第一个答案是解决问题的答案。但事实上它只不过是一个只有一个exec的命令,就像标题所暗示的那样。要用几个命令来回答一个exec,我们将不得不寻找其他东西来解析。这是一个例子:

使用1个exec命令使用多个{}引用保留过去7天内修改过的最近10000行.log文件

1)查看命令将对哪些文件执行的操作:

find / -name "*.log" -a -type f -a -mtime -7 -exec sh -c "echo tail -10000 {} \> fictmp; echo cat fictmp \> {} " \;

2)这样做:(注意不再“\&gt;”但只有“&gt;”这是想要的)

find / -name "*.log" -a -type f -a -mtime -7 -exec sh -c "tail -10000 {} > fictmp; cat fictmp > {} ; rm fictmp" \;

答案 7 :(得分:3)

感谢Camilo Martin,我能够回答相关问题:

我想做的是

find ... -exec zcat {} | wc -l \;

哪个不起作用。但是,

find ... | while read -r file; do echo "$file: `zcat $file | wc -l`"; done

确实有效,谢谢!

答案 8 :(得分:1)

应该使用xargs:)

find *.txt -type f -exec tail -1 {} \; | xargs -ICONSTANT echo $(pwd),CONSTANT

另一个(在osx上工作)

find *.txt -type f -exec echo ,$(PWD) {} + -exec tail -1 {} + | tr ' ' '/'

答案 9 :(得分:0)

一个find+xargs答案。

下面的示例查找所有.html文件,并创建一个附加了.BAK扩展名的副本(例如1.html> 1.html.BAK)。

带有多个占位符的单个命令

find . -iname "*.html" -print0 | xargs -0 -I {} cp -- "{}" "{}.BAK"

具有多个占位符的多个命令

find . -iname "*.html" -print0 | xargs -0 -I {} echo "cp -- {} {}.BAK ; echo {} >> /tmp/log.txt" | sh

# if you need to do anything bash-specific then pipe to bash instead of sh

由于参数引号和-my file.html之后的--(表示cp),该命令也可用于以连字符开头或包含cp之类的文件参数的结尾和实际文件名的开头。

  

-print0用空字节终止符传递结果。


  

对于 xargs -I {}参数将{}定义为占位符;您可以使用任何您喜欢的占位符; -0表示输入项目为空分隔。

答案 10 :(得分:0)

扩展@Tinker的答案,

对于我来说,我需要在command | command | command内制作一个-exec,以在包含特定文本的文件中打印文件名和找到的文本。

我能够做到:

find . -name config -type f \( -exec  grep "bitbucket" {} \; -a -exec echo {} \;  \) 

结果是:

    url = git@bitbucket.org:a/a.git
./a/.git/config
    url = git@bitbucket.org:b/b.git
./b/.git/config
    url = git@bitbucket.org:c/c.git
./c/.git/config

答案 11 :(得分:0)

我通常将find嵌入一个小的for循环一个内衬中,在其中使用$()在子命令中执行查找。

您的命令将如下所示:

for f in $(find *.txt); do echo "$(tail -1 $f), $(ls $f)"; done

好处是,您只使用{}而不是$f,而是使用-exec …do之间的所有命令来代替; done

不确定您实际上想做什么,但是也许像这样?

for f in $(find *.txt); do echo $f; tail -1 $f; ls -l $f; echo; done