3

我有一些像这样命名的文件:

file1.c.keep.apple

file2.c.keep.apple

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

示例执行:

script.sh apple

导致上面的文件被重命名为

文件1.c

文件2.c

到目前为止,我有

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

并且文件不会被重命名。我知道这find部分是正确的。我认为我重命名的正则表达式是错误的。我怎样才能让脚本按我想要的方式工作?

4

6 回答 6

4

我知道这find部分是正确的

除非它不是。

find . -type f -name "*.keep.$1" -print0 | ...
于 2013-01-04T19:53:00.270 回答
3

更新了,试试这个:

#!/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$ 
于 2013-01-04T19:57:07.363 回答
1

我会说你需要:

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

请注意以下限制:

  • 重命名可能并非随处可用。
  • find -print0并且xargs -0是 GNU 扩展,可能并非在所有 Unix 上都可用。
  • 如果您的第一个参数包含正则表达式专用的字符,则结果可能不是您想要的。(例如yourscript "a*e"
于 2013-01-04T20:13:37.110 回答
1

如果您可以假设 bash 和大于 4 的 bash 版本(支持 globstar),那么这是一个干净的 bash-only 解决方案:

#!/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" {} ';'
于 2013-01-05T20:46:48.267 回答
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
于 2013-01-04T20:23:28.287 回答
0

如果你可以简单地 glob 文件,你可以这样做

rename '.keep.apple' '' *

否则你会用你已经拥有*find+替换。xargs

注意这里的rename意思是renameutil-linux。在某些系统上,它的安装方式类似于rename.ul而不是rename.

于 2018-04-19T20:59:17.283 回答