【问题标题】:Bash: execute a command on all files with extension recursivelyBash:递归地对所有带有扩展名的文件执行命令
【发布时间】:2016-07-20 11:48:36
【问题描述】:

我正在尝试使用以下命令:

herbalizer file_name.haml > file_name.erb

这里file_name.haml 显然是文件名。

如何将此命令应用于当前目录中的所有haml 文件,以递归方式应用于所有子目录?文件名应该和上面提到的一样,所以在abc.haml 上申请的是herbalizer abc.haml > abc.erb

到目前为止:find . -type f -exec herbalizer {} \;

【问题讨论】:

    标签: bash recursion find haml erb


    【解决方案1】:

    你已经很接近了。您可以使用basename 去除您找到的每个文件的扩展名:

    find . -type f -name \*.haml -exec sh -c 'herbalizer "{}" > "$(dirname {})/$(basename {} .haml).erb"' \;
    

    我将 i/o 重定向包装在 shell 命令行中。如果文件名或路径组件包含空格,则文件名用引号引起来。

    PS。这让你完成了工作,但它不是很优雅;所以这里有一个使用 bash 内置替换的替代方法:

    find . -type f -name \*.haml -exec bash -c 'FN="{}"; herbalizer "{}" > "${FN%.haml}.erb"' \;
    

    【讨论】:

    • 对不起,我在引用时做得过火了。现已修复。
    • 谢谢,当应用到当前目录时,树好像不再维护了。 Haml 文件被删除并在当前目录而不是它们各自的目录中创建新文件。
    • 好像给定的范围始终是当前目录,而不是文件实际所在的目录。
    • 知道了。请稍等,让我测试一下解决方案。
    • 这个应该可以,再试一次。
    【解决方案2】:

    您可以使用basenamedirnamefind 来获得您想要的结果:

    find . -type f -name "*.haml" | while read fname
    > do
    > herbalizer ${fname} > $(dirname $fname)/$(basename $fname .haml).erb
    > done
    

    @Dummy00001 在 cmets 部分建议的另一种简单方法是:

    find . -type f -name "*.haml" | while read fname
    > do
    > herbalizer ${fname} > ${fname%.haml}.erb
    > done
    

    进一步参考:Parameter substitution

    【讨论】:

    • 您可以将$(dirname $fname)/$(basename $fname .haml).erb 替换为${fname%.haml}.erb
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-09
    • 1970-01-01
    • 2011-01-11
    • 2017-09-22
    • 2021-10-08
    • 2016-08-10
    相关资源
    最近更新 更多