Перемещение нескольких дополнительное имя файла в другом каталоге

#!/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

4
задан 13 November 2015 в 12:25

4 ответа

Используя find с -regex

MOVEFILES=".*\.\(mpg\|avi\|m4v\)"
find "$SOURCE" -type f -regex "$MOVEFILES" -exec mv {} "$DESTDIR" \;

Вы могли также использовать -iregex вместо -regex для матчей случая-insensitve как AvI и так далее.

Весь \ ужасные взгляды, я знаю. -regextype posix-extended, как используется в ответ @Murus , лучше взгляды.

3
ответ дан 23 November 2019 в 11:35

Вы можете сделать это только при помощи раковины (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
6
ответ дан 23 November 2019 в 11:35

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
2
ответ дан 23 November 2019 в 11:35

Необходимо, вероятно, использовать -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 массив.

6
ответ дан 23 November 2019 в 11:35

Другие вопросы по тегам:

Похожие вопросы: