find . -type f > a.txt
cat a.txt | while read FILENAMES; do touch "$FILENAMES"; done
Результат: Шаг 2 «создает файлы» (я имею в виду только с тем же именем файла, но с размером 0 байтов), но если в каталоге «A» есть подкаталоги, то на шаге 2 невозможно создать файлы в подкаталоге, потому что в нем нет каталогов.
Вопрос: Есть ли способ, которым "прикосновение" может создавать каталоги?
быстрый выстрел:
while read FILENAME
do
mkdir -p $(dirname "$FILENAME") && touch "$FILENAME"
done < a.txt
Имейте в виду специальные символы (пробелы, ...) в именах файлов / путей и так далее ...
Я на довольно GNU parallel пинайте в последнее время. Вот способ сделать это одной строкой с помощью этого инструмента:
find A -type d | parallel 'mkdir -p B/$(dirname {})' && find . -type f | parallel 'touch B/{}'
Обратите внимание, что это неэффективно, потому что запускает много лишних ненужных mkdir -p
для справочников-посредников. Это следует оптимизировать, если вы имеете дело с действительно огромными структурами каталогов.
в исходном каталоге "A":
find . -type f > a.txt
Каталог "B":
while read file; do if [[ "$file" = */* ]]; then mkdir -p "${file%/*}"; fi; touch "$file"; done < a.txt
Это работает, даже если A содержит файл:
A / 12-дюймовые пластинки моего брата dir / 12-дюймовые пластинки моего брата
(cd A; find . -type f) | (cd B; parallel 'mkdir -p {//}; touch {}')
Имея дело с пользователями, создающими "креативные" имена файлов, я всегда тестирую подобные сценарии на
My brother's 12" records
Если это сработает, то велики шансы, что он не подведет.
Спасибо Филу Х за основные строительные блоки.
Перед тем как сделать:
cat a.txt | while read FILENAMES; do touch "$FILENAMES"; done
делать:
cat a.txt | sed -e `s|/[^/]*$||` | uniq | while read DIRNAMES; do mkdir -p "$DIRNAMES"; done
Как уже указывалось, будьте осторожны со специальными символами в именах каталогов / имен файлов, особенно с косой чертой (я бы не хотел иметь файл с именем «aaa / ccc», но это всегда возможно).