Я использую поиск для всех файлов в каталоге, поэтому я получаю список путей. Однако мне нужны только имена файлов. т.е. я получаю ./dir1/dir2/file.txt
и хочу получитьfile.txt
267
В GNU find
вы можете использовать -printf
параметр для этого, например:
find /dir1 -type f -printf "%f\n"
-o
имеет более низкий приоритет, чем подразумеваемый-a
, поэтому вы часто захотите сгруппировать свои-o
аргументы)Если в вашем поиске нет опции -printf, вы также можете использовать basename:
источник
... {} ';'
Используйте
-execdir
который автоматически содержит текущий файл{}
, например:Вы также можете использовать
$PWD
вместо.
(в некоторых системах это не приведет к появлению дополнительной точки спереди).Если у вас все еще есть лишняя точка, вы можете запустить:
Когда используется
+
вместо;
, то{}
заменяется таким количеством путей, сколько возможно для каждого вызова утилиты. Другими словами, он напечатает все имена файлов в одну строку.источник
./filename
вместоfilename
. В зависимости от ваших потребностей, это может или не может быть хорошо.$PWD
вместо.
.Если вы используете GNU найти
Или вы можете использовать язык программирования, такой как Ruby (1.9+)
Если вам нравится решение bash (как минимум 4)
источник
Если вы хотите выполнить какое-либо действие только с именем файла, использовать
basename
может быть сложно.Например это:
будет просто повторять базовое имя
/my/found/path
. Не то, что мы хотим, если мы хотим выполнить по имени файла.Но вы можете затем
xargs
на выходе. например, чтобы убить файлы в каталоге, основываясь на именах в другом каталоге:источник
find ~/clang+llvm-3.3/bin/ -type f -exec basename {} \;
На Mac (BSD
find
) используйте:источник
-exec
и-execdir
медленно,xargs
это король.xargs
Параллелизм также помогает.Как ни странно, я не могу объяснить последний случай
xargs
без-n1
. Это дает правильный результат, и это самый быстрый¯\_(ツ)_/¯
(
basename
принимает только 1 аргумент пути, ноxargs
отправит их все (на самом деле 5000) без-n1
. не работает на linux и openbsd, только macOS ...)Несколько больших цифр из системы Linux, чтобы увидеть, как это
-execdir
помогает, но все же намного медленнее, чем параллельxargs
:источник
find
это-execdir
становится самым быстрым, поскольку создание новых процессов - относительно дорогая операция.Честно говоря,
basename
иdirname
решения проще, но вы также можете проверить это:или
или
источник
Как уже отмечали другие, вы можете комбинировать
find
иbasename
, но по умолчаниюbasename
программа будет работать только по одному пути за раз, поэтому исполняемый файл придется запускать один раз для каждого пути (используя либоfind ... -exec
илиfind ... | xargs -n 1
), что потенциально может быть медленным.Если вы используете
-a
опцию onbasename
, то он может принимать несколько имен файлов за один вызов, что означает, что вы можете затем использоватьxargs
без-n 1
, чтобы сгруппировать пути вместе в гораздо меньшее количество вызововbasename
, что должно быть более эффективным.Пример:
Здесь я включил
-print0
и-0
(который должен использоваться вместе), чтобы справиться с любым пробелом в именах файлов и каталогов.Вот сравнение времени, между
xargs basename -a
иxargs -n1 basename
версиями. (Для сравнения «похоже на аналогию» время, указанное здесь, указано после первоначального фиктивного запуска, так что они оба выполняются после того, как метаданные файла уже скопированы в кэш ввода / вывода.) Я передал выходные данные вcksum
в обоих случаях просто для демонстрации того, что вывод не зависит от используемого метода.Как вы можете видеть, это действительно намного быстрее, чтобы избежать запуска
basename
каждый раз.источник
basename
будут приниматься несколько имен файлов без дополнительных аргументов командной строки. Использование-a
здесь на Linux. (basename --version
говорит мнеbasename (GNU coreutils) 8.28
.)Я нашел решение (на странице makandracards), которое дает только самое новое имя файла:
(спасибо Арне Хартцер)
Я использовал это для
cp
:источник