重命名文件并将扩展名保留在bash中

时间:2016-10-21 19:51:42

标签: bash shell

我必须重命名一些我不确切知道它们的位置并保留其扩展名的文件。

Ex:files system-2.1.3.war,system-2.1.3.ear,system-2.1.3.ejb     到system.ear,system.war,system.ejb

所以我写了这个。

find /DIR1 -name "*.ear" -o -name "*.war" -o -name "*.ejb" \ 
-exec bash -c 'export var1={}; cp $var1 NEW_NAME${var1: -4}' \;

问题是:它仅适用于"或列表中的最后一个文件" "发现"命令。因此,如果文件是system-2.1.3.ejb,则对于system-2.1.3.war和system-2.1.3.ear不起作用。

如果我将查找更改为

find /DIR1 -name "*.ejb" -o -name "*.war" -o -name "*.ear"

请注意* .ear现在是最后一个,它适用于system-2.1.3.ear而不适用于其他人等等。

请帮我解决这个问题。

我知道我可以创建一个脚本来实现这一目标,但我想要一个"一行"代码。

4 个答案:

答案 0 :(得分:3)

试试这个;

find /DIR1  \( -name "*.ear" -o -name "*.war"  -o -name "*.ejb" \) -exec bash -c 'export var1={}; cp $var1 NEW_NAME${var1: -4}' \;

find ./DIR1/  -regex  '.*\(.ear\|.war\|.ejb\)$' -exec bash -c 'export var1={}; cp $var1 NEW_NAME${var1: -4}' \;

例如

user@host $ ls -arlt DIR1/
total 76
-rw-rw-r--  1 user user     0 Oct 21 22:59 system-2.1.3.war
-rw-rw-r--  1 user user     0 Oct 21 22:59 system-2.1.3.ear
-rw-rw-r--  1 user user     0 Oct 21 22:59 system-2.1.3.ejb
drwxrwxr-x  2 user user  4096 Oct 21 22:59 .


user@host $ find . \( -name "*.ear" -o -name "*.war"  -o -name "*.ejb" \) -exec bash -c 'export var1={}; cp $var1 NEW_NAME${var1: -4}' \;

user@host $ ls -ralt
total 76
-rw-rw-r--  1 user user     0 Oct 21 22:59 system-2.1.3.war
-rw-rw-r--  1 user user     0 Oct 21 22:59 system-2.1.3.ear
-rw-rw-r--  1 user user     0 Oct 21 22:59 system-2.1.3.ejb
drwxrwxrwt 11 root   root   69632 Oct 21 23:10 ..
-rw-rw-r--  1 user user     0 Oct 21 23:10 NEW_NAME.war
-rw-rw-r--  1 user user     0 Oct 21 23:10 NEW_NAME.ear
-rw-rw-r--  1 user user     0 Oct 21 23:10 NEW_NAME.ejb
drwxrwxr-x  2 user user  4096 Oct 21 23:10 .

答案 1 :(得分:3)

不是在脚本中嵌入{},而是将其作为参数传递:

find /DIR1 \( -name "*.ear" -o -name "*.war" -o -name "*.ejb" \) \ 
  -exec sh -c 'ext=${1##*.}; cp "$1" "NEW_NAME.$ext"' _ '{}' \;

如果没有\(...\)分组,-exec仅适用于主要内容,它是隐含的"并且与前一个分组相同。

您还可以通过循环多个参数来限制对shell的调用次数:

find /DIR1 \( ... \) -exec sh -c 'for f; do ext=${f##*.}; cp "$f" "NEW_NAME.$ext"; done' _ {} +

答案 2 :(得分:2)

如果您有rename实用程序,则可以避免为每个文件分配BASH子流程,并且还可以使用find中的正则表达式功能来避免多个-name选项:

find /DIR1 -regextype awk -regex '.*\.([we]ar|ejb)$' \
    -exec rename 's/.*(\.[^.]+)$/system$1/' '{}' +

答案 3 :(得分:1)

我使用while

find . -name "*.war" -o -name "*.ejb" -o -name "*.ear" | while read file; do cp $file NEW_NAME${file: -4}; done

请注意,此示例和您的示例都在复制当前目录中的文件,因此,如果树中有多个*.war*.ejb*.ear,则只最后一个(s)将保留在目标目录中。