我正在尝试使用find -exec来执行多个命令,但没有成功。 有人知道以下命令是否可行吗?
find *.txt -exec echo "$(tail -1 '{}'),$(ls '{}')" \;
基本上,我正在尝试打印当前目录中每个txt文件的最后一行,并在该行末尾打印逗号,然后是文件名。
find
命令可以多次使用 -exec
参数。例如:
find . -name "*.txt" -exec echo {} \; -exec grep banana {} \;
请注意,在这种情况下,第二个命令只有在第一个命令成功返回时才会运行,正如 @Caleb 所提到的。如果您想让两个命令无论成功或失败都运行,您可以使用这个结构:find . -name "*.txt" \( -exec echo {} \; -o -exec true \; \) -exec grep banana {} \;
-n
来抑制 echo 生成的换行符,如果您的第二个命令只产生一行输出并且您希望它们更易于阅读,则这非常方便。 - William Turrell-exec
的结果传递给grep
吗? find . -iname "*.srt" -exec xattr -l {} | grep "@type" \; > text.txt
- Johnecho
)失败时运行第二个命令(grep banana
):find . -iname '*.zip' \( -exec unzip {} \; -o -exec 7z x {} \; \)
。我的用例是我想尝试使用unzip
解压缩*.zip文件,如果unzip
失败(或找不到),则使用7z
。 - CDuvfind . -type d -exec sh -c "echo -n {}; echo -n ' x '; echo {}" \;
... -exec bash -c ...
代替... -exec sh -c ...
。 - Kenny Evitt{}
。参见https://unix.stackexchange.com/questions/156008/is-it-possible-to-use-find-exec-sh-c-safely - Kusalanandafind . -type d -exec sh -c 'echo -n $0; echo -n " x "; echo $0' "{}" \;
解决了上述评论中提出的问题。 - Jamie Patesh -c "command ${variable}"
很可能会出错。 - Константин Ван以下内容之一:
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"' _ {} \;
$0
的临时值。你可以尝试将下划线 _
替换为 "foobar" 并执行以下命令: find /usr/bin -name find -exec sh -c 'echo "[$0] [$1]"' foobar {} \;
,输出结果为 "[foobar] [/usr/bin/find]"。 - Dennis Williamson$0
通常是程序名称(ARGV[0]
)。 - Dennis Williamsonsh -c
命令的脚本要用单引号而不是双引号。否则,$1
变量会出现错误作用域。 - Nick\$1
),就可以写成"$1"
。您还可以转义其他字符("\""
)。@Nick的引用与此无关。 - Camilo Martin另一种方法是这样的:
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可以像您需要的那样长和复杂。
希望这可以帮助您。
〜/ aaa $ acmd(){echo x“$ 1”x;}; export-f acmd; find。-exec bash-c'acmd {}'\;
- barlop有更简单的方法:
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 ...)"
zcat $file | wc -l
"; done 可以工作,所以谢谢! - Greg Dougherty\``来实现,方法是使用反斜杠
`,像这样:\\``(不过,这也是使用
$()`的另一个好理由)。 - Camilo Martin在扩展@Tinker的答案时,
在我的情况下,我需要在-exec
中创建一个command | command | command
来打印包含某些文本的文件的文件名和找到的文本。
我使用以下命令实现了这个目标:
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
-exec
参数和在grep
命令中将/dev/null
作为第二个参数传递,您还可以在单行上打印文件名和经过grep
筛选的内容:
find . -name config -type f -exec grep "bitbucket" {} /dev/null \;
- Bill Feth$ find . -name config -type f -exec grep -nl "bitbucket" {} \;
它只会打印与之匹配的文件名。 - Paulo Henrique Lellis Gonalvesgrep -H
正是如此。它会打印出文件名和匹配的行。 - Emsi我不知道你是否可以使用find来完成这个任务,但另一种解决方法是创建一个shell脚本,并使用find来运行此脚本。
lastline.sh:
echo $(tail -1 $1),$1
使脚本可执行
chmod +x lastline.sh
find
:find . -name "*.txt" -exec ./lastline.sh {} \;
find ... -exec zcat {} | wc -l \;
这并没有起作用。然而,
find ... | while read -r file; do echo "$file: `zcat $file | wc -l`"; done
能够正常工作,所以谢谢你!
Denis的第一个答案是解决问题的答案。但实际上,它不再是一个只有一个exec中的几个命令可以找到的东西,就像标题所示。为了回答带有多个命令的单个exec的问题,我们将不得不寻找其他方法来解决。以下是一个例子:
使用一个exec命令并使用多个{}引用,保留最近7天内已修改的.log文件的最后10000行。
1)查看该命令将在哪些文件上执行:
find / -name "*.log" -a -type f -a -mtime -7 -exec sh -c "echo tail -10000 {} \> fictmp; echo cat fictmp \> {} " \;
2) 执行它:(注意不再有"\>",只有">"是需要的)
find / -name "*.log" -a -type f -a -mtime -7 -exec sh -c "tail -10000 {} > fictmp; cat fictmp > {} ; rm fictmp" \;
我通常将find
命令嵌入一个小的for
循环一行代码中,其中find命令在使用$()
子命令执行。
然后您的命令将如下所示:
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
SC2044: For loops over find output are fragile. Use find -exec or a while read loop.
在ShellCheck的维基 https://github.com/koalaman/shellcheck/wiki/Sc2044 上有一个很好的示例和描述。 - Alex Baranowski
find /path/to/search -type f -exec chmod 755 {} \; -exec chown user:group {} \; -type d -exec chmod 775 {} \; -exec chown user:group {} \;
在这个例子中,-type选项用于区分文件类型,{}代表当前找到的文件名,;指示-exec参数的结束。请注意,在最后一个-exec参数之后也需要使用-type选项来匹配目录类型。 - Ignacio Vazquez-Abramsfind
手册页面上可以看到:使用-exec
选项存在无法避免的安全问题,你应该使用-execdir
选项来代替。详见:http://unixhelp.ed.ac.uk/CGI/man-cgi?find - JVE999