.
├── subdirectory-A
│ ├── 1.jpg
│ ├── 1.tif
│ ├── 2.jpg
│ ├── 2.tif
│ ├── JPEG
│ └── TIF
└── subdirectory-B
├── 1.jpg
├── 1.tif
├── 2.jpg
├── 2.tif
├── JPEG
└── TIF
Кто-либо может помочь? Я пытаюсь найти способ переместить все .tif
файлы в каталог TIF и все .jpg
файлы в каталог JPEG путем выполнения (mv
) в сценарии оболочки из локального родительского каталога. Я использовал
mv *.jpg JPEG/
в каждом подкаталоге, но я должен сделать это задание на архиве с по 17K каталогам и ручной опции, один dir за один раз не является опцией.
Можно сделать это с rename
использование bash
globstar
опция:
shopt -s globstar
rename -n 's/.*\//$&JPEG\//' **/*.jpeg
rename -n 's/.*\//$&TIF\//' **/*.tif
-n
опция позволяет ему просто произвести то, что это сделает, удалит его для фактического выполнения перемещения. Что происходит, вот это rename
пробегается через каждого, например. .jpeg
файл в любом подкаталоге благодаря **
соответствие любому количеству подкаталогов. Это заменяет своим путем (все до последнего /
) с собой ($&
) сопровождаемый JPEG/
, эффективно перемещая файл в этот каталог.
Если Ваш список аргументов будет слишком длинным, то команды выше бросят ошибку. Используйте этот подход для работы вокруг оболочки ARG_MAX
предел:
printf '%s\0' **/*.jpeg | xargs -0 rename -n 's/.*\//$&JPEG\//'
printf '%s\0' **/*.tif | xargs -0 rename -n 's/.*\//$&TIF\//'
Это использует встроенную оболочку printf
создавать разграниченный нулем список аргументов, который передается по каналу к xargs
который звонит rename
с максимальным количеством аргументов.
$ tree
.
├── subdirectory-A
│ ├── 1.jpeg
│ ├── 1.tif
│ ├── 2.jpeg
│ ├── 2.tif
│ ├── JPEG
│ └── TIF
└── subdirectory-B
├── 1.jpeg
├── 1.tif
├── 2.jpeg
├── 2.tif
├── JPEG
└── TIF
$ shopt -s globstar
$ rename -n 's/.*\//$&JPEG\//' **/*.jpeg
rename(subdirectory-A/1.jpeg, subdirectory-A/JPEG/1.jpeg)
rename(subdirectory-A/2.jpeg, subdirectory-A/JPEG/2.jpeg)
rename(subdirectory-B/1.jpeg, subdirectory-B/JPEG/1.jpeg)
rename(subdirectory-B/2.jpeg, subdirectory-B/JPEG/2.jpeg)
$ rename 's/.*\//$&JPEG\//' **/*.jpeg
$ printf '%s\0' **/*.tif | xargs -0 rename 's/.*\//$&TIF\//'
$ tree
.
├── subdirectory-A
│ ├── JPEG
│ │ ├── 1.jpeg
│ │ └── 2.jpeg
│ └── TIF
│ ├── 1.tif
│ └── 2.tif
└── subdirectory-B
├── JPEG
│ ├── 1.jpeg
│ └── 2.jpeg
└── TIF
├── 1.tif
└── 2.tif
Первой вещью, которая прибывает по моему мнению, является следующий цикл Bash:
#!/bin/bash
for dir in */ # or use: subdirectory*/
do
cd "$dir"
mv *jpg JPG/
mv *tif TIF/
cd ..
done
Пример использования как встроенная команда:
$ mkdir -p subdirectory-{A,B}/{TIF,JPG}; touch subdirectory-{A,B}/{1,2}.{jpg,tif}
$ for dir in */; do cd "$dir"; mv *jpg JPG/; mv *tif TIF/; cd ..; done
$ tree
.
├── subdirectory-A
│ ├── JPG
│ │ ├── 1.jpg
│ │ └── 2.jpg
│ └── TIF
│ ├── 1.tif
│ └── 2.tif
└── subdirectory-B
├── JPG
│ ├── 1.jpg
│ └── 2.jpg
└── TIF
├── 1.tif
└── 2.tif
6 directories, 8 files
Связанные вопросы:
Так как Вы упомянули "по 17K каталогам", find
и xargs
прийти на ум.
# do this part Only Once
cat >./TheScript <<"EOF"
#!/bin/bash
while $# -gt 0 ; do
cd "$1"
find . -maxdepth 1 -type f -name '*.jpg' -print | xargs --no-run-if-empty mv --target-directory=JPG
find . -maxdepth 1 -type f -name '*.tif' -print | xargs --no-run-if-empty mv --target-directory=TIF
cd "$OLDPWD"
shift
done
exit 0
EOF
chmod +x ./TheScript
# end of "Only Once"
find . -type d \! -name 'JPG' -a \! -name 'TIF` -print |\
xargs $PWD/.TheScript