查找和基本名称不能很好地播放

Mat*_*ins 39 linux find

我想在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 ; 这里讨论的其余部分适用于您可能遇到的任何版本.basenamefindfind


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)

  • 无需在那里使用管道、叉子和子壳 (2认同)

mao*_*urf 7

这就是我如何使用imagick批量调整文件大小,从源代码重新输出输出文件名

find . -name header.png -exec sh -c 'convert -geometry 600 {} $(dirname {})/$(basename {} ".png")_mail.png' \;
Run Code Online (Sandbox Code Playgroud)