我想在linux命令行上回显一个find的文件名部分.我试过使用以下内容:
find www/*.html -type f -exec sh -c "echo $(basename {})" \;
Run Code Online (Sandbox Code Playgroud)
和
find www/*.html -type f -exec sh -c "echo `basename {}`" \;
Run Code Online (Sandbox Code Playgroud)
以及许多其他组合,包括逃避和引用文本的各个部分.结果是路径没有被剥离:
www/channel.html
www/definition.html
www/empty.html
www/index.html
www/privacypolicy.html
Run Code Online (Sandbox Code Playgroud)
为什么不?
更新:虽然我有一个工作解决方案,但我仍然对"basename"没有做它应该做的事情感兴趣.
Jon*_*ler 54
原始尝试的麻烦:
find www/*.html -type f -exec sh -c "echo $(basename {})" \;
Run Code Online (Sandbox Code Playgroud)
是在$(basename {})
执行find
命令之前执行一次代码.单个的输出basename
是{}
因为它是{}
文件名的基本名称.所以,find执行的命令是:
sh -c "echo {}"
Run Code Online (Sandbox Code Playgroud)
对于找到的每个文件,但find
实际上每次都替换原始(未修改的)文件名,因为{}
字符出现在要执行的字符串中.
如果您希望它工作,您可以使用单引号而不是双引号:
find www/*.html -type f -exec sh -c 'echo $(basename {})' \;
Run Code Online (Sandbox Code Playgroud)
但是,echo
重复basename
标准输出无论如何都要写入标准输出有点无意义:
find www/*.html -type f -exec sh -c 'basename {}' \;
Run Code Online (Sandbox Code Playgroud)
当然,我们可以进一步减少这一点:
find www/*.html -type f -exec basename {} \;
Run Code Online (Sandbox Code Playgroud)
你能解释单引号和双引号之间的区别吗?
这是常规的shell行为.让我们采取略微不同的命令(但只是略微 - 文件的名称可以在www
目录下的任何位置,而不仅仅是一个级别),并查看单引号(SQ)和双引号(DQ)版本的命令:
find www -name '*.html' -type f -exec sh -c "echo $(basename {})" \; # DQ
find www -name '*.html' -type f -exec sh -c 'echo $(basename {})' \; # SQ
Run Code Online (Sandbox Code Playgroud)
单引号将直接包含的材料传递给命令.因此,在SQ命令行中,启动的shell将find
删除封闭的引号,并且find
命令将其$9
参数视为:
echo $(basename {})
Run Code Online (Sandbox Code Playgroud)
因为shell删除了引号.相比之下,双引号中的材料由shell处理.因此,在DQ命令行外壳(即启动find
-而不是一个推出的 find
)看到$(basename {})
该字符串的一部分,并执行它,找回{}
,因此字符串它传递给find
它的$9
参数是:
echo {}
Run Code Online (Sandbox Code Playgroud)
现在,find
它的-exec
动作是什么时候,在两种情况下它都会替换{}
它刚刚找到的文件名(为了参数www/pics/index.html
).因此,您将执行两个不同的命令:
sh -c 'echo $(basename www/pics/index.html)' # SQ
sh -c "echo www/pics/index.html" # DQ
Run Code Online (Sandbox Code Playgroud)
那里有一个(轻微的)符号作弊 - 那些是你在shell上输入的等效命令.将$2
在两种情况下,实际上是启动了壳中有没有引号-启动的外壳没有看到任何报价.
如您所见,DQ命令只是回显文件名; SQ命令运行basename
命令并捕获其输出,然后回显捕获的输出.一点点还原思维表明DQ命令可以写成-print
而不是使用-exec
,而SQ命令可以写成-exec basename {} \;
.
如果你正在使用GNU find
,它支持格式指令-printf
可以遵循的操作,这样就不需要运行了.但是,这只适用于GNU ; 这里讨论的其余部分适用于您可能遇到的任何版本.basename
find
find
Gil*_*not 13
试试这个:
find www/*.html -type f -printf '%f\n'
Run Code Online (Sandbox Code Playgroud)
如果您想使用管道(需要更多资源):
find www/*.html -type f -print0 | xargs -0 -n1 basename
Run Code Online (Sandbox Code Playgroud)
这就是我如何使用imagick批量调整文件大小,从源代码重新输出输出文件名
find . -name header.png -exec sh -c 'convert -geometry 600 {} $(dirname {})/$(basename {} ".png")_mail.png' \;
Run Code Online (Sandbox Code Playgroud)