bash:如何仅更改文件列表的基本名称

时间:2009-08-24 12:33:31

标签: bash rename prefix

  

可能重复:
  makefile: how to add a prefix to the basename?

我有一些文件(我从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中做到这一点的任何想法?

6 个答案:

答案 0 :(得分:6)

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

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

不需要循环,因为find已经进行了递归工作以列出文件。代码逐个构建“mv”命令并执行它们。要在不执行它们的情况下查看“mv”命令,只需删除管道部件“| bash”。

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

  • %h:目录
  • %f:filename

如何测试

首先运行(暂时不执行任何操作,仅在屏幕上打印行):

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

答案 1 :(得分:5)

有些事情:

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

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

答案 2 :(得分:2)

while multiliner

基于$ 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&lt;不干扰stdin
  • -print0 + IFS = + -d $'/ 0'允许文件名中的换行符
  • sort -rz首先重命名更深的路径,以便您甚至可以立即重命名目录及其中的文件

find -execdir + rename

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

答案 3 :(得分:1)

尝试mmv

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

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

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

答案 4 :(得分:0)

basename和dirname是你的朋友:)

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

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

击败拳头!

答案 5 :(得分: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