Bash 重命名扩展递归

Posted

技术标签:

【中文标题】Bash 重命名扩展递归【英文标题】:Bash rename extension recursive 【发布时间】:2011-01-11 10:23:54 【问题描述】:

我知道周围有很多这样的东西,但是它们要么不能递归工作,要么很大。

这是我得到的:

find . -name "*.so" -exec mv  `echo  | sed s/.so/.dylib/` \;

当我只运行查找部分时,它会给我一个文件列表。当我运行 sed 部分时,它会将任何 .so 替换为 .dylib。当我一起运行它们时,它们不起作用。

我把 mv 换成了 echo 看看发生了什么:

./AI/Interfaces/C/0.1/libAIInterface.so ./AI/Interfaces/C/0.1/libAIInterface.so

什么都没有被替换! 怎么了?

【问题讨论】:

【参考方案1】:

一个用于重命名文件扩展名的 bash 脚本

  #/bin/bash
  find -L . -type f -name '*.'$1 -print0 | while IFS= read -r -d '' file; do
      echo "renaming $file to $(basename $file%.$1.$2)";
      mv -- "$file" "$file%.$1.$2";
  done

感谢aps2012。

用法

    创建一个文件,例如称为ext-rename(没有扩展名,所以你可以像命令一样运行它)在例如/usr/bin(确保将/usr/bin 添加到您的$PATH) 在终端中的任意位置运行ext-rename [ext1] [ext2],其中[ext1] 正在重命名,[ext2] 正在重命名为。一个示例用法是:ext-rename so dylib,它将任何扩展名为 .so 的文件重命名为相同的名称,但扩展名为 .dylib

【讨论】:

喜欢这个,效果很好,而且速度很快。谢谢。【参考方案2】:

这一切都会正确

找到 -L 。 -type f -name "*.so" -print0 |而 IFS= 读取 -r -d '' FNAME;做 mv -- "$FNAME" "$FNAME%.so.dylib" 完毕

正确的意思是:

1) 它将重命名只是文件扩展名(由于使用了$FNAME%.so.dylib)。使用$X/.so/.dylib 的所有其他解决方案都不正确,因为它们错误地重命名了文件名中.so第一次出现(例如,x.so.so 被重命名为x.dylib.so,或者更糟糕的是,./libraries/libTemp.so-1.9.3/libTemp.so 是重命名为 ./libraries/libTemp.dylib-1.9.3/libTemp.so - 错误)。

2) 它将处理文件名中的空格和任何其他特殊字符(双引号除外)。

3) 它不会改变目录或其他特殊文件。

4) 它将跟随符号链接进入子目录并链接到目标文件并重命名目标文件,而不是链接本身(find 的默认行为是处理符号链接本身,而不是链接指向的文件) .

【讨论】:

太棒了!最后一个真正有效的解决方案。谢谢一百万!【参考方案3】:

他需要递归:

#!/bin/bash

function walk_tree 
    local directory="$1"
    local i

    for i in "$directory"/*; 
        do
            if [ "$i" = . -o "$i" = .. ]; then 
                continue
            elif [ -d "$i" ]; then  
            walk_tree "$i"  
            elif [ "$i##*." = "so" ]; then
                echo mv $i $i%.*.dylib    
            else
                continue
            fi
        done    


walk_tree "."

【讨论】:

【参考方案4】:

如果你有 Bash 4

#!/bin/bash

shopt -s globstar
shopt -s nullglob
for file in /path/**/*.so
do
 echo mv "$file"  "$file/%.so.dylib"
done

【讨论】:

【参考方案5】:
for X in `find . -name "*.so"` 
do
 mv $X $X/.so/.dylib
done

【讨论】:

如果任何目录或文件名可能包含空格,请用 ". 引用 mv 的两个参数 @Lachlan:这本身无济于事。你必须做 find ... | while read X 而不是 for (并做引用)。此外,该查找应该有一个-type f Why you shouldn't parse the output of ls(1)【参考方案6】:

错在

echo | sed s/.so/.dylib/ 只执行一次,在启动 find 之前,sed 在其输入中给出 ,它与 /.so/ 不匹配并且保持不变,所以你得到的命令行是 找 。 -name "*.so" -exec mv

【讨论】:

谢谢!我应该意识到......不知何故......任何尚未提及的解决方案?

以上是关于Bash 重命名扩展递归的主要内容,如果未能解决你的问题,请参考以下文章

ubuntu /bash 下递归重命名文件和目录

用于递归重命名文件夹的 Bash 脚本

重命名递归文件扩展名

递归批量重命名文件扩展名(Windows批处理)

如何在 MacOS 中递归地重命名文件夹和文件

BASH one liner重命名文件夹中所有文件的扩展名