在另一个目录中移动多个扩展文件名

jay*_*six 4 bash scripts mv

#!/bin/bash
# script to find and move files

SOURCE=/DRIVE2/folder/
DESTDIR=/DRIVE/new3/

MOVEFILES=(mpg avi m4v mp4 3gp mpeg MOV) 
# this line above is not working, its only reading the first extension

find $SOURCE -type f -name *.$MOVEFILES -print | xargs -i mv -v "{}" $DESTDIR 
Run Code Online (Sandbox Code Playgroud)

你们能帮我写 bash 脚本吗?在$MOVEFILES我的脚本的一部分不能正常工作。它只是读取我放在那里的第一个扩展名,即mpg. 其余的都被忽略了。写那行的正确方法是什么?

还可以包含它的目录,让我们说 /DRIVE2/folder1/folder2/folder3/folder4/file.ext移动到/DRIVE/folder3/folder4/file.ext

mur*_*uru 6

您可能应该使用-regex而不是-name- with -name,每个扩展都需要单独-name测试:

find .. -name '*.mp4' -name '*.avi' ...
Run Code Online (Sandbox Code Playgroud)

反而:

find -regextype posix-extended ... -regex '.*\.(mp4|avi|...)' ...
Run Code Online (Sandbox Code Playgroud)

给定你的数组,做(抛弃不必要的xargs):

find "$SOURCE" -regextype posix-extended  -type f -regex ".*\.($(IFS="|"; echo "${MOVEFILES[*]}"))" -exec mv -t "$DESTDIR" {} +
Run Code Online (Sandbox Code Playgroud)

IFS="|"; echo "${MOVEFILES[*]}"是一种打印MOVEFILES|.分隔的数组中每个元素的方法。

$MOVEFILES本身只是MOVEFILES数组中的第一个元素。


hee*_*ayl 6

您可以仅使用 shell ( bash)来执行此操作:

shopt -s extglob globstar nullglob 
mv -t /destination **/*(*.mpg|*.m4v|*.mpeg|*.mp4|*.avi|*.3gp|*.MOV)
Run Code Online (Sandbox Code Playgroud)
  • 首先我们需要设置几个shell选项

  • extglob 将使我们能够对文件名进行扩展模式匹配

  • globstar, 启用后,通过使用**我们可以遍历子目录来搜索文件

  • nullglob 如果没有文件名与我们给定的模式而不是模式本身匹配,则将导致空字符串

  • 现在,*(*.foo|*.bar)是一个extglob匹配零次或多次出现的*.foo*.bar

  • 所以结合起来,**/*(*.mpg|*.m4v|*.mpeg|*.mp4|*.avi|*.3gp|*.MOV)会让我们得到要移动的文件

  • mv -t /destination **/*(*.mpg|*.m4v|*.mpeg|*.mp4|*.avi|*.3gp|*.MOV)将文件移动到/destination.

例子:

$ tree 
.
??? dest
??? foo
?   ??? bar
?   ?   ??? baz.md
?   ?   ??? egg.3gp
?   ?   ??? egg.mp4
?   ??? baz.txt
?   ??? spam.avi
?   ??? spam.mp3
??? spamegg.MOV
??? spamegg.txt


$ shopt -s extglob globstar nullglob 

$ mv -t dest/ **/*(*.mp3|*.mp4|*.avi|*.3gp|*.MOV)

$ tree 
.
??? dest
?   ??? egg.3gp
?   ??? egg.mp4
?   ??? spam.avi
?   ??? spamegg.MOV
?   ??? spam.mp3
??? foo
?   ??? bar
?   ?   ??? baz.md
?   ??? baz.txt
??? spamegg.txt
Run Code Online (Sandbox Code Playgroud)

  • 旁注(不适合你 heemayl,对于其他阅读本文的人):当 Bash 以非交互方式运行时(脚本、`bash -c` 等),`extglob` 始终处于禁用状态,但在 Bash 以交互方式运行时它始终处于启用状态,因此您除非您从脚本(或从“bash -c”)运行它,否则不需要打开“extglob”。 (2认同)