Рекурсивное перемещение файлов с расширением в целевой каталог в Bash

Как я могу переместить все файлы .txt из папки и все включенные папки в целевой каталог.

И желательно переименовать их в папку, в которой они находятся, хотя это не так важно. Я не совсем знаком с bash.


person Mehran    schedule 15.01.2013    source источник


Ответы (3)


Чтобы рекурсивно перемещать файлы, объедините find с mv.

find src/dir/ -name '*.txt' -exec mv {} target/dir/ \;

Переименовывать файлы при их перемещении сложнее. Один из способов — создать цикл, который пропускает каждое имя файла через tr / _, что преобразует косые черты в символы подчеркивания.

find src/dir/ -name '*.txt' | while read file; do
    mv "$file" "target/dir/$(tr / _ <<< "$file")"
done
person John Kugelman    schedule 15.01.2013
comment
Версия, которая будет работать с файлами, содержащими встроенные символы новой строки, или начинаться с пробелов: find src/dir -name '*.txt' -exec bash -c 'mv "$1" "${1//\//_}"' _ {} ';' - person Josh Cartwright; 16.01.2013

Попробуй это:

find source -name '*.txt' | xargs -I files mv files target

Это будет работать быстрее, чем любой параметр с -exec, поскольку он не будет вызывать отдельный процесс mv для каждого файла, который необходимо переместить.

person Mithrandir    schedule 15.01.2013
comment
Намного, намного быстрее, чем принятый ответ. Обратите внимание, что для надежности рекомендуется использовать строки имен файлов, заканчивающиеся нулем: find source -name '*.txt' -print0 | xargs -0 -I files mv files target - person cooperised; 04.03.2017
comment
Я пробовал это, но он перемещает неожиданные типы файлов. Я хотел переместить только файлы .srt, но по какой-то причине это также перемещает файлы .srt и .mkv. Я попытался использовать метод Cooperised и вижу такое же поведение. При тестировании я нахожусь в каталоге с десятью подкаталогами, в каждом подкаталоге есть несколько файлов .srts и несколько файлов .mkv. Почему эта команда перемещает неожиданные файлы .mkv? Что бы это ни стоило, я работаю в Mac OS и использую стандартное приложение Terminal со стандартным Bash. Тестовая команда ниже: find . '*.srt' -print0 | xargs -0 -I files mv files. - person adamlogan; 16.09.2019

Если это только один уровень:

mv *.txt */*.txt target/directory/somewhere/.
person DigitalRoss    schedule 15.01.2013