我知道有很多这样的事情,但要么他们不能递归地工作,要么他们是巨大的。
这就是我得到的:
find . -name "*.so" -exec mv {} `echo {} | sed s/.so/.dylib/` \;
当我运行查找部分时,它会给我一个文件列表。当我运行sed部分时,它用.dylib替换任何.so。当我一起运行它们时它们不起作用。
我用echo替换了mv,看看发生了什么:
./AI/Interfaces/C/0.1/libAIInterface.so ./AI/Interfaces/C/0.1/libAIInterface.so
根本没有替换! 有什么问题?
答案 0 :(得分:24)
这将完成所有正确:
find -L . -type f -name "*.so" -print0 | while IFS= read -r -d '' FNAME; do mv -- "$FNAME" "${FNAME%.so}.dylib" done
正确地说,我们的意思是:
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的默认行为是处理符号链接本身,而不是链接指向的文件)
答案 1 :(得分:4)
for X in `find . -name "*.so"`
do
mv $X ${X/.so/.dylib}
done
答案 2 :(得分:4)
#/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
。答案 3 :(得分:3)
有什么问题
echo {} | sed s/.so/.dylib/
只执行一次,在find
启动之前,sed
在其输入上被赋予{}
,与/.so/
不匹配且保持不变,因此您得到的命令线是
find . -name "*.so" -exec mv {} {}
答案 4 :(得分:1)
如果你有Bash 4
#!/bin/bash
shopt -s globstar
shopt -s nullglob
for file in /path/**/*.so
do
echo mv "$file" "${file/%.so}.dylib"
done
答案 5 :(得分:0)
他需要递归:
#!/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 "."