[英]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.