我有一些文件(我从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中做到这一点的任何想法?
答案 0 :(得分:6)
find . -name "*.so" -printf "mv '%h/%f' '%h/lib%f'\n" | bash
代码将重命名当前目录和子目录中的文件,以便在.so文件名前添加“lib”。
不需要循环,因为find
已经进行了递归工作以列出文件。代码逐个构建“mv”命令并执行它们。要在不执行它们的情况下查看“mv”命令,只需删除管道部件“| bash”。
find
的printf命令可以理解许多变量,使其具有很强的可扩展性。我只需要在这里使用两个:
如何测试:
首先运行(暂时不执行任何操作,仅在屏幕上打印行):
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)
这非常强大:
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