Я не изучал вывод с символическими ссылками, но:
find . -type f -iname '*.c' -printf '%h\0' |
sort -z |
uniq -zc |
sed -zr 's/([0-9]) .*/\1 1/' |
tr '\0' '\n' |
awk '{f += $1; d += $2} END {print f, d}'
Команда find печатает имя каталога каждого найденного файла .c. sort | uniq -c предоставит нам, сколько файлов находится в каждом каталоге (здесь sort может быть ненужным, а не обязательно) с помощью sed, я заменяю имя каталога на 1, тем самым устраняя все возможные странные символы, счетчик и 1 останутся, позволяя мне преобразовать вывод, выделенный в новую строку, с помощью tr, который затем я суммирую с awk, чтобы получить общее количество файлов и количество каталогов, содержащих эти файлы. Обратите внимание, что d здесь по существу совпадает с NR. Я мог бы пропустить вставку 1 в команду sed и просто напечатать NR здесь, но я думаю, что это немного яснее. До tr данные делятся на NUL, безопасны для всех допустимых имен файлов.
С помощью zsh и bash вы можете использовать [ f19], чтобы получить строку с кавычками, в которой не было бы новых строк. Таким образом, вы можете сделать что-то вроде:
shopt -s globstar dotglob nocaseglob
printf "%q\n" **/*.c | awk -F/ '{NF--; f++} !c[$0]++{d++} END {print f, d}'
Однако, хотя ** не предполагается расширять для символических ссылок на каталоги, я не смог получить желаемый результат в bash 4.4.18 (1) (Ubuntu 16.04).
$ shopt -s globstar dotglob nocaseglob
$ printf "%q\n" ./**/*.c | awk -F/ '{NF--; f++} !c[$0]++{d++} END {print f, d}'
34 15
$ echo $BASH_VERSION
4.4.18(1)-release
Но zsh работал нормально, и команда может быть упрощена:
$ printf "%q\n" ./**/*.c(D.:h) | awk '!c[$0]++ {d++} END {print NR, d}'
29 7
D позволяет этому глобусу выбирать точечные файлы , . выбирает обычные файлы (так, а не символические ссылки), а :h печатает только путь к каталогу, а не имя файла (например, find %h) (см. разделы ** не предполагается расширить для символических ссылок на каталоги и модификаторы). Таким образом, с помощью команды awk нам просто нужно подсчитать количество уникальных каталогов, а количество строк - количество файлов.
Большинство программ резервного копирования сжимают данные в специализированные архивы резервного копирования.
Если вам нужна только точная копия файлов, рассмотрите команду rsync.
d2] Заимствование из этого ответа: сценарий Bash для клонирования Ubuntu для нового раздела для тестирования 18.04. Обновление LTS здесь - это клонирование полной установки 16.04:
rsync -haxAX --stats --delete --info=progress2 --info=name0 /* "$TargetMnt" \
--exclude={/dev/*,/proc/*,/sys/*,/tmp/*,/run/*,/mnt/*,/media/*,/lost+found}
Некоторые заметные комментарии о параметрах:
--stats предоставляет информацию о файлах, добавленных, измененных и удаленных из клона (так называемая резервная копия в вашем случае). --delete инструктирует rsync удалять файлы в клоне, которые больше не существуют в исходном каталоге. info=progress2 дает современный вид отображения прогресса во время клонирования каталогов. --info=name0 предотвращает отображение каждого имени файла при его копировании. Это дает меньше помех для экрана, но вы можете опустить этот параметр. /* сообщает rsync, где начать синхронизацию файлов. В этом примере это корневой каталог, но вы хотите изменить его на /media/user1/DATA4/FolderA. "$TargetMnt" сообщает rscync, где клонировать. В вашем случае измените его на "/media/ivan/Seagate Backup Plus Drive/FolderA". Двойные кавычки важны, потому что имена ваших каталогов содержат пробелы. Вторая строка, начинающаяся с --exclude={/dev/*, вам совсем не нужна, потому что эти каталоги не входят в список. Не используйте эту строку и оставьте символ продолжения строки \ в конце первой строки.Как и во всех сценариях резервного копирования, всегда проверяйте резервные копии, чтобы убедиться, что все файлы есть и содержат соответствующую информацию.
Большинство программ резервного копирования сжимают данные в специализированные архивы резервного копирования.
Если вам нужна только точная копия файлов, рассмотрим команду rsync.
d2] Заимствование из этого ответа: сценарий Bash для клонирования Ubuntu для нового раздела для тестирования 18.04. Обновление LTS здесь - это клонирование полной установки 16.04:
rsync -haxAX --stats --delete --info=progress2 --info=name0 /* "$TargetMnt" \
--exclude={/dev/*,/proc/*,/sys/*,/tmp/*,/run/*,/mnt/*,/media/*,/lost+found}
Некоторые заметные комментарии о параметрах:
--stats предоставляет информацию о файлах, добавленных, измененных и удаленных из клона (так называемая резервная копия в вашем случае). --delete инструктирует rsync удалять файлы в клоне, которые больше не существуют в исходном каталоге. info=progress2 дает современный вид отображения прогресса во время клонирования каталогов. --info=name0 предотвращает отображение каждого имени файла при его копировании. Это дает меньше помех для экрана, но вы можете опустить этот параметр. /* сообщает rsync, где начать синхронизацию файлов. В этом примере это корневой каталог, но вы хотите изменить его на /media/user1/DATA4/FolderA. "$TargetMnt" сообщает rscync, где клонировать. В вашем случае измените его на "/media/ivan/Seagate Backup Plus Drive/FolderA". Двойные кавычки важны, потому что имена ваших каталогов содержат пробелы. Вторая строка, начинающаяся с --exclude={/dev/*, вам совсем не нужна, потому что эти каталоги не входят в список. Не используйте эту строку и оставьте символ продолжения строки \ в конце первой строки.Как и во всех сценариях резервного копирования, всегда проверяйте резервные копии, чтобы убедиться, что все файлы есть и содержат соответствующую информацию.
Большинство программ резервного копирования сжимают данные в специализированные архивы резервного копирования.
Если вам нужна только точная копия файлов, рассмотрите команду rsync.
d2] Заимствование из этого ответа: сценарий Bash для клонирования Ubuntu для нового раздела для тестирования 18.04. Обновление LTS здесь - это клонирование полной установки 16.04:
rsync -haxAX --stats --delete --info=progress2 --info=name0 /* "$TargetMnt" \
--exclude={/dev/*,/proc/*,/sys/*,/tmp/*,/run/*,/mnt/*,/media/*,/lost+found}
Некоторые заметные комментарии о параметрах:
--stats предоставляет информацию о файлах, добавленных, измененных и удаленных из клона (так называемая резервная копия в вашем случае). --delete инструктирует rsync удалять файлы в клоне, которые больше не существуют в исходном каталоге. info=progress2 дает современный вид отображения прогресса во время клонирования каталогов. --info=name0 предотвращает отображение каждого имени файла при его копировании. Это дает меньше помех для экрана, но вы можете опустить этот параметр. /* сообщает rsync, где начать синхронизацию файлов. В этом примере это корневой каталог, но вы хотите изменить его на /media/user1/DATA4/FolderA. "$TargetMnt" сообщает rscync, где клонировать. В вашем случае измените его на "/media/ivan/Seagate Backup Plus Drive/FolderA". Двойные кавычки важны, потому что имена ваших каталогов содержат пробелы. Вторая строка, начинающаяся с --exclude={/dev/*, вам совсем не нужна, потому что эти каталоги не входят в список. Не используйте эту строку и оставьте символ продолжения строки \ в конце первой строки.Как и во всех сценариях резервного копирования, всегда проверяйте резервные копии, чтобы убедиться, что все файлы есть и содержат соответствующую информацию.
Большинство программ резервного копирования сжимают данные в специализированные архивы резервного копирования.
Если вам нужна только точная копия файлов, рассмотрите команду rsync.
d2] Заимствование из этого ответа: сценарий Bash для клонирования Ubuntu для нового раздела для тестирования 18.04. Обновление LTS здесь - это клонирование полной установки 16.04:
rsync -haxAX --stats --delete --info=progress2 --info=name0 /* "$TargetMnt" \
--exclude={/dev/*,/proc/*,/sys/*,/tmp/*,/run/*,/mnt/*,/media/*,/lost+found}
Некоторые заметные комментарии о параметрах:
--stats предоставляет информацию о файлах, добавленных, измененных и удаленных из клона (так называемая резервная копия в вашем случае). --delete инструктирует rsync удалять файлы в клоне, которые больше не существуют в исходном каталоге. info=progress2 дает современный вид отображения прогресса во время клонирования каталогов. --info=name0 предотвращает отображение каждого имени файла при его копировании. Это дает меньше помех для экрана, но вы можете опустить этот параметр. /* сообщает rsync, где начать синхронизацию файлов. В этом примере это корневой каталог, но вы хотите изменить его на /media/user1/DATA4/FolderA. "$TargetMnt" сообщает rscync, где клонировать. В вашем случае измените его на "/media/ivan/Seagate Backup Plus Drive/FolderA". Двойные кавычки важны, потому что имена ваших каталогов содержат пробелы. Вторая строка, начинающаяся с --exclude={/dev/*, вам совсем не нужна, потому что эти каталоги не входят в список. Не используйте эту строку и оставьте символ продолжения строки \ в конце первой строки.Как и во всех сценариях резервного копирования, всегда проверяйте резервные копии, чтобы убедиться, что все файлы есть и содержат соответствующую информацию.