Основная причина этой проблемы удивительно короткая: .
(да: точка).
Помните, что find
(без каталога) эквивалентен find.
.
Из man find
:
Если пути не указаны, используется текущий каталог.
И, когда вы выполняете находите.
точка появляется в сгенерированном списке
(для упрощения используются только четыре файла с разными именами):
$ find ### Works the same with or without the dot.
.
./2014-08-09-163849.jpg
./2014-04-12-134210.jpg
./Webcam
./Webcam/2015-04-29-202242.jpg
./Webcam/2015-08-27-230306.jpg
И затем вы передаете этот список ls -R
(рекурсивно).
Просто точка воспроизведет все файлы:
$ ls -1R . ### The 1 will make the list 1 column.
.:
Webcam
2014-04-12-134210.jpg
2014-08-09-163849.jpg
./Webcam:
2015-04-29-202242.jpg
2015-08-27-230306.jpg
Поэтому неудивительно, что все файлы появляются дважды (один раз для точки, один раз для поиска).
$ find -exec ls -1R {} \;
.:
2014-04-12-134210.jpg
2014-08-09-163849.jpg
Webcam
./Webcam:
2015-04-29-202242.jpg
2015-08-27-230306.jpg
./2014-08-09-163849.jpg
./2014-04-12-134210.jpg
./Webcam:
2015-04-29-202242.jpg
2015-08-27-230306.jpg
./Webcam/2015-04-29-202242.jpg
./Webcam/2015-08-27-230306.jpg
\ (! -Name. -Prune \) -a
). Удалите точку из списка найденных файлов в find:
$ find . \( ! -name . -prune \) -a -print
./2014-08-09-163849.jpg
./2014-04-12-134210.jpg
./Webcam
Затем вы можете использовать рекурсивный ls -R
:
$ find . \( ! -name . -prune \) -a -exec ls -1R {} \;
./2014-08-09-163849.jpg
./2014-04-12-134210.jpg
./Webcam:
2015-04-29-202242.jpg
2015-08-27-230306.jpg
ls -d
). Не использовать рекурсивный ls -R
(с также параметром -d
, чтобы избежать расширения в каталоги) и пусть find
выполняет обход дерева чтобы найти все файлы:
$ find . ! -path . -exec ls -1d {} \;
./2014-08-09-163849.jpg
./2014-04-12-134210.jpg
./Webcam
./Webcam/2015-04-29-202242.jpg
./Webcam/2015-08-27-230306.jpg
Конечно, для конкретного использования архивирования:
вам не нужны имена каталогов, только имена файлов с полным путем:
$ find . ! -path ./ -type f -a -exec ls -1R {} \;
./2014-08-09-163849.jpg
./2014-04-12-134210.jpg
./Webcam/2015-04-29-202242.jpg
./Webcam/2015-08-27-230306.jpg
найти каталог
(не точка). Если вы используете путь, проблема будет той же, если глубина каталогов больше единицы.
Это не вызовет проблемы:
$ find Webcam -exec ls -1R {} \;
Webcam:
2015-04-29-202242.jpg
2015-08-27-230306.jpg
Webcam/2015-04-29-202242.jpg
Webcam/2015-08-27-230306.jpg
Однако увеличение глубины на единицу (cd ..) приведет к:
$ cd ..
$ find jpg -exec ls -1R {} \;
jpg:
2014-04-12-134210.jpg
2014-08-09-163849.jpg
Webcam
jpg/Webcam:
2015-04-29-202242.jpg
2015-08-27-230306.jpg
jpg/2014-08-09-163849.jpg
jpg/2014-04-12-134210.jpg
jpg/Webcam:
2015-04-29-202242.jpg
2015-08-27-230306.jpg
jpg/Webcam/2015-04-29-202242.jpg
jpg/Webcam/2015-08-27-230306.jpg
чего это не сработает:
$ find jpg \( ! -path ./jpg -prune \) -exec ls -1R {} \;
jpg:
2014-04-12-134210.jpg
2014-08-09-163849.jpg
Webcam
jpg/Webcam:
2015-04-29-202242.jpg
2015-08-27-230306.jpg
Я настаиваю на использовании двух рекурсивных инструментов очень опрометчивый .
Измените структуру на более простую, например find jpg -ls
или даже попробуйте предоставленное оболочкой решение для листинга, подобное echo **
:
$ (shopt -s globstar nullglob; printf '%s\n' jpg/**/*)
jpg/2014-04-12-134210.jpg
jpg/2014-08-09-163849.jpg
jpg/Webcam
jpg/Webcam/2015-04-29-202242.jpg
jpg/Webcam/2015-08-27-230306.jpg