我必须重命名一些我不确切知道它们的位置并保留其扩展名的文件。
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而不适用于其他人等等。
请帮我解决这个问题。
我知道我可以创建一个脚本来实现这一目标,但我想要一个"一行"代码。
答案 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)将保留在目标目录中。