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

perl -l -0777ne 'print for /(?:^|\n)\n\K.+(?=\n\n)/g' yourfile

Объяснение:

Мы сжимаем файл, и весь файл представляет собой одну запись. В этой единственной записи мы увеличиваем острова, которым предшествуют 2 последовательных начала строки и за которыми следуют 2 новые строки. Все такие острова печатаются циклом for.


sed -e '
   /./d      # skip a nonempty line
   $!N       # grab the line following an empty line
   /^\n$/D   # if we have 2 consecutive empties, clip the former, n branch to top
   $!N       # we now have ^\nLine\n...
   /\n$/!D   # clip if the seq ^\nLine\n$ not found
   s/.//     # found it! ^\nLine\n$
   P;D       # 
' yourfile
1
13.04.2017, 15:36
1 ответ

Прежде всего, я не могу воспроизвести результаты, которые вы заявляете для команды, которую вы показали. Я получил файлы, которые переименовываются в другой файл_каталога1.jpg , другой файл_каталога2.jpg и т. Д., но все же в некоторых каталогах каталогах.

Во-вторых, из-за глубины структуры каталогов вам следует использовать -mindepth 4 вместо 2 . В-третьих, я настоятельно рекомендую вам использовать -тип f . Пока вы используете -name '* .jpg' , вы, вероятно, не найдете никаких каталогов. Но через шесть-восемь недель вы посмотрите на это и подумаете: «Я хочу, чтобы это применимо ко всем моим файлам - мне не нужно говорить -name '*.jpg ' », и выньте его. А затем, если у вас нет -типа f , команда find может начать поиск каталогов и их переименование. А изменение дерева каталогов во время его сканирования - это верный путь к катастрофе (например, пословица «летать на самолете, пока мы его строим»).

В-четвертых, команда rename для перемещения файла на три уровня вверх и префикса его имени с помощью Directory _

rename     -n     's!/[^/]+/[^/]+/([^/]+)$!_$1!'
        (optionally)

, потому что / [^ /] + представляет уровень каталога, поэтому я просто добавил еще две его копии.

Предупреждение: это, как я уже сказал, переместит файл на три уровня вверх. Если у вас есть файлы, расположенные глубже в дереве каталогов, они не будут переименованы в верхний уровень; они могут быть переименованы во что-то вроде Directory 3 / некоторый файл_каталога3.jpg .

Но оказывается, это легко исправить. Чтобы переместить файл на верхний уровень с любой глубины, на которой он находится на , и добавьте к его имени префикс Directory _ , просто используйте

s!(\./[^/]+)/.*/([^/]+)$/$1_$2/!

TL; DR

Итак,

Последняя команда -

find . -mindepth 4 -type f -exec rename -n 's!/[^/]+/[^/]+/([^/]+)$!_$1!' {} +

Добавить -name '* .jpg' , если хотите. Удалите -n , когда выходные данные трассировки показывают, что все работает правильно.

Помните, что это может привести к конфликту файлов. Если у вас есть файлы

Directory 1/some directory/another directory/sunrise.jpg

и

Directory 1/some directory/another directory/mountains/sunrise.jpg

, эта команда попытается переименовать их оба в Directory 1_sunrise.jpg . К счастью, программа переименовать кажется достаточно умной и дружелюбной , чтобы не причинить вреда в этом случае. Первый такой файл, который он увидит, (вероятно) будет переименован; остальные останутся на месте (и вы получите уведомление). (Вы можете использовать -f или - force , чтобы принудительно перезаписать существующие файлы.) Но помните, что некоторые другие программы (например,, mv ) имеют менее дружественные действия по умолчанию.


Относительно обновленного вопроса («Как я могу включить все имена каталогов в имена файлов?»): это немного сложнее. Я предполагаю, что мы ищем . , , поэтому все пути будут начинаться с ./ . И я обнаружил, что аргумент perlexpr для переименовать на самом деле может содержать несколько команд изменения строки. Таким образом, мы можем переместить все файлы на верхний уровень и добавить к их именам все имена каталогов в пути с помощью

s!^\./!!;s!/!_!g

. Это также может привести к конфликту файлов.

Directory 1/abc/def_ghi/sunrise.jpg

и

Directory 1/abc_def/ghi/sunrise.jpg

(потенциально) будут переименованы в Directory 1_abc_def_ghi_sunrise.jpg .


Заявление об ограничении ответственности: Я тестировал это, но не совсем тщательно. Я не гарантирую, что это будет работать идеально. Перед выполнением вышеуказанных команд необходимо сделать полную резервную копию.

1
27.01.2020, 23:48

Теги

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