我试图使用查找-exec与多个命令没有任何成功。有人知道像下面这样的命令是否可行吗?

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

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


当前回答

有一个更简单的方法:

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 ...)"

其他回答

find+xargs的答案。

下面的例子找到所有的.html文件,并创建一个附加了. bak扩展名的副本(例如1.html > .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表示输入项为空分隔。

感谢Camilo Martin,我得以回答一个相关的问题:

我想做的是

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

但这并不奏效。然而,

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

确实有用,所以谢谢!

我通常将find嵌入到一个小的for循环一行中,其中find在带有$()的子命令中执行。

你的命令看起来像这样:

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

好的一点是,你不用{}只用$f,不用-exec…你把所有的命令都写在do和;完成了。

不知道你到底想做什么,但也许像这样?

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

下列其中一项:

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"' _ {} \;

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

保留在过去7天内使用一个exec命令使用几个{}引用修改的.log文件的最后10000行

1)看看这个命令会对哪些文件做什么:

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

2)这样做:(注意没有更多的“\>”,而只有“>”,这是需要的)

查找/ -name "*.log" -a -type f -a -mtime -7 -exec sh -c "tail -10000 {} > fictmp;Cat fictmp > {};Rm fictmp" \;