Как скопировать или переместить файлы -n уровня вверх на OSX через оболочку
Как я могу найти все файлы определенного типа / имени и скопировать их на уровень выше? Вот древовидная структура файловой системы:
germany/
|
adventure/
|
300x600/
| |
| file1.jpg
| file2.zip
|
400x600/
|
file8.jpg
file4.zip
switzerland/
|
adventure/...
Есть много страновых папок, около 20, и файлы.zip не гарантированно будут иметь 3 уровня глубины. Я в настоящее время в их родительской папке, countries/
и я хочу найти и скопировать все .zip файлы на один уровень вверх, на adventure/
каталог соответствующей страны / папки.
Я старался:
find . -type f -name '*.zip' -exec mv {}/.. \;
но тот с треском провалился. Он перемещал каждый файл на один уровень вверх, затем они снова перемещались на один уровень вверх.
Спасибо!
РЕДАКТИРОВАТЬ: я немного поиграл с решениями из ответов и прочитал много man
страницы:). Наконец, я принял решение, которое мне понравилось больше всего, так как оно элегантное и не зависит от оболочки.
Что-то я все еще пытаюсь выяснить:
- Есть ли
find
работать как цикл или фигурные скобки считаются списком / массивом в других языках программирования? Значение: он заполняется найденными результатами (т. Е. Строками) одновременно и ТО передается команде-exec
? - Почему движение сначала произошло на один уровень вверх, а затем снова на один уровень вверх?
- Есть ли способ сразу сказать
mv/cp
перейти на -n уровни [вверх / вниз]?
3 ответа
Вы можете сделать его независимым от оболочки и объединить его в один find
команда:
find . -type f -name '*.zip' -exec \
sh -c 'echo cp -- "$0" "$(dirname "$0")"/..' {} \;
Удалить echo
когда вы уверены, что он делает то, что вы хотите.
использование find
чтобы найти файлы. Выполнить оболочку с -exec sh -c
, передав найденный файл с {}
в качестве первого аргумента этой оболочки. Поэтому в оболочке путь к файлу будет доступен как $0
,
Вы можете использовать dirname "$0"
и подстановка команды ($(…)
), чтобы получить родительский каталог файла. Добавить как можно больше /..
как вы хотите пройти выше.
Обратите внимание, что я цитировал имена файлов, чтобы предотвратить неправильное расширение файлов с символами новой строки или пробелами в их имени.
Попробовал это с ubuntu zsh 5.0.2:
for pdir in */
do
cd $pdir
for dir in */
do
cd $dir
mv */*.zip .
cd ..
done
cd ..
done
Просто быстрая альтернатива, если реальность так проста, как приведенный пример:
cd germany
mv */*/*.zip .
(и там не миллионы файлов)