简体   繁体   English

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

[英]Rename file and keep the extension in bash

I have to rename some files that I don't exactly know where they are and keep their extensions. 我必须重命名一些我确切不知道它们在哪里的文件,并保留其扩展名。

Ex: files system-2.1.3.war, system-2.1.3.ear, system-2.1.3.ejb to system.ear, system.war,system.ejb 例如:将system-2.1.3.war,system-2.1.3.ear,system-2.1.3.ejb归档到system.ear,system.war,system.ejb

So I wrote this. 所以我写了这个。

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

The problem is: It works only for the last file in the "or list" of "find" command. 问题是:它仅对“查找”命令的“或列表”中的最后一个文件有效。 So if the file is system-2.1.3.ejb, works, for system-2.1.3.war and system-2.1.3.ear don't. 因此,如果文件为system-2.1.3.ejb,则正常运行,而对于system-2.1.3.war和system-2.1.3.ear则无效。

If I change the find to 如果我将查找更改为

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

Notice that *.ear now is the last one, it will work for system-2.1.3.ear and not for the others and so on. 请注意,*。ear现在是最后一个,它将适用于system-2.1.3.ear,而不适用于其他。

Please help me to fix this. 请帮助我解决此问题。

I know I can create a script to accomplish that but I want a "one line" code. 我知道我可以创建一个脚本来完成该任务,但是我需要一个“一行”代码。

try this; 尝试这个;

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

or 要么

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

Eg; 例如;

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 .

Rather than embedding the {} in the script, pass it as an argument: 与其将{}嵌入脚本中,不如将其作为参数传递:

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

Without the \\(...\\) grouping, -exec only applies to the primary it is implicitly "and"ed with, the previous one. 如果没有\\(...\\)分组,则-exec仅适用于隐式“与”前一级的主数据库。

You can also limit the number of calls to the shell by looping over multiple arguments: 您还可以通过循环多个参数来限制对外壳程序的调用次数:

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

If you have rename utility then you can avoid forking BASH subprocess for each file and also make use of regex feature in find to avoid multiple -name options: 如果您具有rename实用程序,则可以避免为每个文件分叉BASH子进程,还可以在find使用正则表达式功能来避免使用多个-name选项:

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

I'd use a while : 我会用一段while

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

Keep in mind that both this and your example are copying the files in the current directory, so if you have more than one *.war , *.ejb or *.ear in your tree, only the last one(s) will be left in the target directory. 请记住,此例和您的示例都在复制当前目录中的文件,因此,如果树中有多个*.war*.ejb*.ear ,则仅剩下最后一个在目标目录中。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM