
У меня есть большая папка, содержащая много подкаталогов, каждый из которых содержит много .txt
файлов. Я хочу объединить все эти файлы в один .txt
файл. Я могу сделать это для каждого из подкаталогов с помощью cat *.txt>merged.txt
, но я пытаюсь сделать это для всех файлов в большой папке. Как мне это сделать?
решение1
попробуйте с
find /path/to/source -type f -name '*.txt' -exec cat {} + >mergedfile
f
рекурсивно найти все файлы «*.txt» /path/to/source
в подкаталогах и объединить все в один mergedfile
.
Чтобы объединить файлы каждого подкаталога в его каталоге, выполните:
find . -mindepth 1 -type d -execdir sh -c 'cat $1/*.txt >> $1/mergedfile' _ {} \;
решение2
Если вы используете Bash и количество текстовых файлов ограничено (т.е. не превышает максимального предела числа аргументов, который очень велик, но не бесконечен), вы можете легко добиться этого с помощью функции globstar
:
$ shopt -s globstar
$ cat **/*.txt > merged.txt
Более общий, хотя и менее элегантный подход — использовать find
драйвер и заставить его вызывать cat
каждый файл, добавляя вывод:
$ find -name \*.txt -exec sh -c 'cat {} >> merged.out' \;
Вызов sh
здесь необходим, поскольку вы хотите добавить результат каждого cat
. Убедитесь, что выходной файл имеет другое расширение или находится за пределами дерева, которое вы объединяете, или find
можете попытаться объединить вывод с самим собой.
решение3
Если вам необходимо выполнить объединение в определенном порядке, то нижеприведенная команда объединит файлы в лексикографическом порядке (сортируя по именам путей) в bash
:
shopt -s globstar
for name in **/*.txt; do
[ -f "$name" ] && cat <"$name"
done >merged.out
Это похоже на find
команду
find . -type f -name '*.txt' -exec cat {} ';' >merged.out
за исключением того, что порядок может быть другим, символические ссылки на обычные файлы будут включены (добавьте , && [ ! -L "$name" ]
если они вам не нужны), а скрытые файлы (и файлы в скрытых каталогах) будут исключены (используйте , shopt -s dotglob
чтобы добавить их обратно).