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 重命名扩展递归的主要内容,如果未能解决你的问题,请参考以下文章