Linux shell脚本查找并重命名文件以删除后缀?

时间:2013-01-04 19:50:03

标签: linux bash shell

我有一些名为这样的文件:

file1.c.keep.apple

file2.c.keep.apple

我正在尝试编写一个shell脚本,以便将后缀作为参数传递(在本例中为apple),它将重命名删除.keep.apple的所有文件。

执行示例:

script.sh apple

导致上述文件重命名为

file1.c中

file2.c中

到目前为止,我有

 #! /bin/sh
 find . -type f -name \'*.keep.$1\' -print0 | xargs -0 rename 's/\(.keep.*)$//'

并且文件未重命名。我知道find部分是正确的。我认为重命名的正则表达式是错误的。如何让脚本以我想要的方式工作?

7 个答案:

答案 0 :(得分:4)

  

我知道find部分是正确的

除非不是。

find . -type f -name "*.keep.$1" -print0 | ...

答案 1 :(得分:2)

更新,或许试试这个:

#!/bin/bash

SUFFIX=$1;

find . -type f -name "*keep.${SUFFIX}" | while read -r file;
do 
    nfile=`echo $file | sed "s/\.keep\.${SUFFIX}//g"`; 
    mv "$file" "$nfile" 2>/dev/null; 
done

这里正在运行:

jgalley@jgalley-debian:/test5$ cat replace.sh 
#!/bin/bash

SUFFIX=$1;

find . -type f -name "*keep.${SUFFIX}" | while read -r file;
do 
    nfile=`echo $file | sed "s/\.keep\.${SUFFIX}//g"`; 
    mv "$file" "$nfile" 2>/dev/null; 
done
jgalley@jgalley-debian:/test5$ find .
.
./-filewithadash.keep.apple
./dir1
./dir1/file
./dir1/file2.keep.orange
./dir2
./dir2/file2
./file with spaces
./file.keep.orange
./file.keep.somethingelse.apple
./file.orange
./replace.sh
jgalley@jgalley-debian:/test5$ ./replace.sh apple
jgalley@jgalley-debian:/test5$ find .
.
./-filewithadash
./dir1
./dir1/file
./dir1/file2.keep.orange
./dir2
./dir2/file2
./file with spaces
./file.keep.orange
./file.keep.somethingelse.apple
./file.orange
./replace.sh
jgalley@jgalley-debian:/test5$ 

答案 2 :(得分:1)

我说你需要:

find . -type f -name "*.keep.$1" -print0 | xargs -0 rename "s/\.keep\.$1$//"

请注意以下限制:

  • 重命名可能无处不在。
  • find -print0xargs -0是GNU扩展,可能并非在所有Unix上都可用。
  • 如果您的第一个参数包含特殊于正则表达式的字符,则结果可能不是您想要的。 (例如yourscript "a*e"

答案 3 :(得分:1)

如果你可以假设bash,以及bash大于4的版本(支持globstar),这里只是一个干净的bash解决方案:

#!/usr/bin/env bash

(($#)) || exit 1

shopt -s globstar nullglob
for f in **/*.keep."$1"; do
    mv -- "$f" "${f%.keep.$1}"
done

或者,这是一个使用findwhile read循环的解决方案(假设找到GNU或BSD):

find . -type f -name "*.keep.$1" -print0 | while IFS= read -r -d '' f; do
    mv -- "$f" "${f%.keep.$1}"
done

有关此解决方案的详细信息,请参阅http://mywiki.wooledge.org/BashFAQ/030

此外,您可以使用find -exec来实现您尝试执行的操作:

find . -type f -name "*.keep.$1" -exec sh -c 'mv -- "$2" "${2%.keep.$1}"' _ "$1" {} ';'

答案 4 :(得分:0)

这个怎么样?

[spatel@us tmp]$ x=aa.bb.cc
[spatel@us tmp]$ y=${x%.cc}
[spatel@us tmp]$ echo $y
aa.bb


[spatel@us tmp]$ x=aa.bb.cc
[spatel@us tmp]$ y=${x%.bb.cc}
[spatel@us tmp]$ echo $y
aa

答案 5 :(得分:0)

更短的:

shopt -s globstar
rename 's/\.keep\.apple$//' **/*.keep.apple

(要求perl)

答案 6 :(得分:0)

如果您可以简单地对文件进行全局处理,则可以执行

rename '.keep.apple' '' *

否则您会将*替换为您已有的find + xargs

rename中的rename表示来自util-linux的{​​{1}}。在某些系统上,它的安装方式类似于rename.ul而不是rename