13

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

这就是我得到的:

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

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

我用 echo 替换了 mv 以查看发生了什么:

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

什么都换不了!
怎么了?

4

6 回答 6

25

这将正确地做所有事情:

找到 -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 的默认行为是处理符号链接本身,而不是链接指向的文件)。

于 2012-04-26T04:00:34.223 回答
4
for X in `find . -name "*.so"` 
do
 mv $X ${X/.so/.dylib}
done
于 2010-01-31T14:20:48.440 回答
4

通常重命名文件扩展名的 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 。

用法

  1. 在例如(确保添加到您的)中创建一个名为ext-rename(无扩展名,因此您可以像命令一样运行它)的文件/usr/bin/usr/bin$PATH
  2. ext-rename [ext1] [ext2]在终端的任何地方运行,[ext1]从哪里重命名和[ext2]重命名到哪里。一个示例用法是:ext-rename so dylib,它将任何具有扩展名的文件重命名.so为相同的名称但具有扩展名.dylib
于 2013-03-18T13:24:54.113 回答
3

有什么不对的是

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

于 2010-01-31T14:37:27.660 回答
1

如果你有 Bash 4

#!/bin/bash

shopt -s globstar
shopt -s nullglob
for file in /path/**/*.so
do
 echo mv "$file"  "${file/%.so}.dylib"
done
于 2010-01-31T15:42:14.593 回答
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 "."
于 2010-01-31T14:56:34.513 回答