如果我只使用 basename {} .txt,它会起作用:
find . -iname "*.txt" -exec basename {} .txt \;
Run Code Online (Sandbox Code Playgroud)
它只会打印 xxx 而不是 ./xxx.txt
如果我想在 -exec 选项中使用 $(basename {} .txt) ,它将失败:
find . -iname "*.txt" -exec echo "$(basename {} .txt)" \;
Run Code Online (Sandbox Code Playgroud)
它只会打印 ./xxx.txt
我怎么解决这个问题?我希望我可以$(basename {} .txt)
用作其他 cmd 的参数。我必须用 xargs做sh -c
或管道-exec basename {} \;
吗?
尝试:
find -iname "*.txt" -exec sh -c 'for f do basename -- "$f" .txt;done' sh {} +
Run Code Online (Sandbox Code Playgroud)
你的第一个命令失败了,因为$(...)
在子shell中运行,它被{}
视为文字。所以basename {} .txt
返回{}
,你find
变成了:
find . -iname "*.txt" -exec echo {} \;
Run Code Online (Sandbox Code Playgroud)
哪个打印文件名匹配。
小智 9
$()
如果使用sh -c
and 单引号,您仍然可以用于命令替换:
find . -iname "*.txt" -exec sh -c 'echo "$(basename {} .txt)"' \;
Run Code Online (Sandbox Code Playgroud)
单引号防止主 shell 执行内部的子命令,因此可以在命令替换为文件名后$()
执行它。请参阅Stack Overflow 上的这个答案以获得更全面的解释。sh -c
find
{}
请注意,您还可以在 内添加双引号$()
来处理文件名中的空格:
find . -iname "*.txt" -exec sh -c 'echo "$(basename "{}" .txt)"' \;
Run Code Online (Sandbox Code Playgroud)
小智 6
相反,还有另一种使用 bash 管道和xargs
命令的方法:
find . -iname '*.txt' | xargs -L1 -I{} basename "{}"
Run Code Online (Sandbox Code Playgroud)
在xargs
上面的命令中:
参数表示逐行执行命令行-L1
的输出。find
该-I{}
参数旨在find
用双引号括起命令的输出,以避免 bash 分词(当文件名包含空格时)。