#!/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
Можете Вы парни помогать мне с моим сценарием удара? $MOVEFILES
часть моего сценария не работает. Это только читает первое расширение, которое я поместил там, который является mpg
. Остальное игнорируется. Что надлежащий путь состоит в том, чтобы записать той строке?
Также, это возможный включать каталог от позволяет, говорят /DRIVE2/folder1/folder2/folder3/folder4/file.ext
переместитесь в /DRIVE/folder3/folder4/file.ext
Используя find
с -regex
MOVEFILES=".*\.\(mpg\|avi\|m4v\)"
find "$SOURCE" -type f -regex "$MOVEFILES" -exec mv {} "$DESTDIR" \;
Вы могли также использовать -iregex
вместо -regex
для матчей случая-insensitve как AvI
и так далее.
Весь \
ужасные взгляды, я знаю. -regextype posix-extended
, как используется в ответ @Murus , лучше взгляды.
Вы можете сделать это только при помощи раковины (bash
):
shopt -s extglob globstar nullglob
mv -t /destination **/*(*.mpg|*.m4v|*.mpeg|*.mp4|*.avi|*.3gp|*.MOV)
Сначала мы должны установить несколько вариантов раковины
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
find
команда позволяет устанавливать несколько условий с -o
флаг, и Вам действительно не нужно xargs
, Вы можете использовать -exec
. Лично, я изменил бы Ваш сценарий на
#!/bin/bash
# script to find and move files
SOURCE=/DRIVE2/folder/
DESTDIR=/DRIVE/new3/
find "$SOURCE" -type f \( -name -o "*.mpg" -o -name "*.avi" -o -name "*.m4v" -o -name "*.mp4" -o -name "*.3gp" -o -name "*.mpeg" -o -name "*.MOV" \) -exec mv -t "$DESTDIR" {} +
, Другой подход будет с для петли, где мы работаем над каждым расширением индивидуально
for EXT in ${MOVEFILES[@]}; do find "$SOURCE" -type f -name "*.$EXT" -exec mv -t "$DESTDIR" {} + ; done
Необходимо, вероятно, использовать -regex
вместо -name
- с -name
, для каждого расширения будет нужно отдельное -name
тест:
find .. -name '*.mp4' -name '*.avi' ...
Вместо этого:
find -regextype posix-extended ... -regex '.*\.(mp4|avi|...)' ...
Учитывая Ваш массив, сделайте (отказ от ненужного xargs
):
find "$SOURCE" -regextype posix-extended -type f -regex ".*\.($(IFS="|"; echo "${MOVEFILES[*]}"))" -exec mv -t "$DESTDIR" {} +
IFS="|"; echo "${MOVEFILES[*]}"
путь состоит в том, чтобы распечатать каждый элемент в MOVEFILES
массив, разделенный |
.
$MOVEFILES
отдельно просто первый элемент в MOVEFILES
массив.