2

可能重复:
makefile:如何为基本名称添加前缀?

我有很多文件(我从中获得find bla -name "*.so"),例如:

/bla/a1.so /bla/a2.so /bla/blo/a3.so /bla/blo/a4.so /bla/blo/bli/a5.so

我想将它们重命名为:

/bla/liba1.so /bla/liba2.so /bla/blo/liba3.so /bla/blo/liba4.so /bla/blo/bli/liba5.so

...即将前缀“lib”添加到基本名称

关于如何在 bash 中做到这一点的任何想法?

4

6 回答 6

7

类似于以下内容:

for a in /bla/a1.so /bla/a2.so /bla/blo/a4.so
do
  dn=$(dirname $a)
  fn=$(basename $a)
  mv "$a" "${dn}/lib${fn}"
done

应该这样做。当然,您可能希望添加代码以从文件中读取文件名列表,而不是在脚本中逐字列出它们。

于 2009-08-24T12:37:40.347 回答
6
find . -name "*.so" -printf "mv '%h/%f' '%h/lib%f'\n" | bash

该代码将重命名当前目录和子目录中的文件,以在 .so 文件名前附加“lib”。

不需要循环,因为find它已经完成了列出文件的递归工作。代码一一构建“mv”命令并执行它们。要查看“mv”命令而不执行它们,只需删除外壳部分“| bash”的管道。

find的 printf 命令可以理解许多变量,这使得它非常具有可扩展性。我只需要在这里使用两个:

  • %h: 目录
  • %f: 文件名

如何测试它

首先运行它(什么都不做,只在屏幕上打印行):

find . -name "*.so" -printf "mv '%h/%f' '%h/lib%f'\n" | less -S

这将向您显示脚本将执行的所有命令。如果您对结果感到满意,只需在之后通过管道将其输入bash而不是less.

find . -name "*.so" -printf "mv '%h/%f' '%h/lib%f'\n" | bash
于 2009-08-24T12:43:12.203 回答
2

while多线

基于 $nfm 的稍微更强大和更通用的解决方案(可能比您真正需要的更多)将是

while IFS= read -r -u3 -d $'\0' FILE; do
    DIR=`dirname $FILE`;
    FILENAME=`basename $FILE`;
    mv $FILE ${DIR}/lib${FILENAME};
done 3< <(find bla -name *.so -print0 | sort -rz)

这是非常强大的:

  • 读取 -u3 和 3< 不会干扰标准输入
  • -print0 + IFS= + -d $'/0' 允许在文件名中使用换行符
  • sort -rz 首先重命名更深的路径,这样您甚至可以一次重命名目录和其中的文件

find -execdir+rename

如果不是因为 PATH 的烦恼,这将是完美的,请参阅:Find multiple files and rename them in Linux

于 2012-06-20T08:14:45.690 回答
1

尝试mmv

cd /bla/
mmv "*.so" "lib#1.so"

mmv "*" "lib#1"也可以,但不太安全)。

如果你还没有mmv安装,请获取它。

于 2009-08-24T12:38:55.027 回答
0

basename 和 dirname 是你的朋友 :)

你想要这样的东西(请原谅我的 bash 语法 - 它有点生疏):

for FILE in `find bla -name *.so` do
    DIR=`dirname $FILE`;
    FILENAME=`basename $FILE`;
    mv $FILE ${DIR}/lib${FILENAME};
done

被打得一塌糊涂!

于 2009-08-24T12:40:06.150 回答
0

注意我已经注释掉了 mv 命令以防止任何意外的混乱

for f in *
do
    dir=`dirname "$f"`
    fname=`basename "$f"`
    new="$dir/lib$fname"
    echo "new name is $new"
    # only uncomment this if you know what you are doing
    # mv "$f" "$new" 
done
于 2009-08-24T12:45:04.950 回答