#!/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
您可能应该使用-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数组中的第一个元素。
您可以仅使用 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)