Как вернуть только имена файлов из команды поиска?

13

Я ищу, чтобы получить список только имен файлов (без остальной части пути) при выполнении команды поиска из терминала. Как мне сделать это на Mac?

blueberryfields
источник

Ответы:

17

С базовым именем:

find . -type f -exec basename {} \;

Пауло Алмейда
источник
Для чего нужны фигурные скобки?
нульпотентен
Базовое имя запускается один раз для каждого найденного файла, обозначается {}.
Ярослав Рахматуллин
что означает «\»; ?
Neouyghur
@neouyghur ;прекращает -execдействие. \ Необходимо потому , что ;имеет особое значение для оболочки.
8bittree
6

Evilsoup упомянул, что то, что было опубликовано, не работает для имен файлов с интервалом. Так что вместо этого вы можете использовать:

find . -type f -print0 | while IFS= read -r -d '' filename; do echo ${filename##*/}; done
nerdwaller
источник
Это сломает файлы с пробелами в их именах (см. Парсинг ls на вики
Грега
+1 за скорость. Я не знаю, сделал ли я что-то не так, но это заняло 1 секунду на моем $ HOME, тогда как все остальные заняли около 10 секунд. Конечно, мне нужно больше 10 секунд, чтобы найти и напечатать.
Пауло Алмейда
2

С помощью GNU find вы можете сделать:

 find ~/tmp/ -printf "%f\n"

Это, вероятно, стоит попробовать и в OS X.

Ярослав Рахматуллин
источник
2
-printfне поддерживается на BSD OS X в find.
Даниэль Бек
1
Кроме того, -printfимеет мало отношения к printfутилите оболочки C или POSIX printf. Использование этого исторического имени функции для чего-то другого очень плохо продумано. Консервативные парни из BSD, вероятно, видят это так же, поэтому мы, вероятно, не увидим клонов -printfв находке BSD под этим именем.
Каз
Я не согласен с тем, что плохо принято использовать знакомое имя функции для выполнения аналогичной задачи в другом контексте. Почему BSD, вероятно, никогда не поддержит это другой вопрос.
Ярослав Рахматуллин
2

Есть лучший способ удалить все, кроме последней части пути к файлу; с awk. Это лучше, потому что awk не выполняется один раз для каждого файла. В некоторых случаях это имеет значение.

find ~/tmp/ -type f  | awk -F/ '{ print $NF }'

Мы ищем только файлы в ~ / tmp и получаем список, в котором каждая запись отделена косой чертой. Следовательно, мы используем косую черту в качестве разделителя полей (-F /) и печатаем параметр поля ($ 1 .. $ 9), который соответствует последнему полю ($ NF).

Ярослав Рахматуллин
источник
Это самый быстрый, который я тестировал.
Пауло Алмейда
В последнее время я пользуюсь Cygwin, а создание процесса в windows - это очень дорого ...
Ярослав Рахматуллин
2

РЕДАКТИРОВАТЬ :

Использование sed:

$ find . -type f | sed 's/.*\///'

Использование команды xargs , как указано в ответе @nerdwaller

$ find . -type f -print0 | xargs --null -n1 basename
STDERR
источник
1
Спасибо за указание на это, +1, я не очень много использовал xargs ... Определенно, так как вы сбросили довольно много символов из моей команды.
ботаник
Этот ломается, когда файлы имеют пробелы. Это работает так, по крайней мере, в быстром тесте:find . -type f -print0| xargs --null -n1 basename
Пауло Алмейда
Ни OSF, --nullни -n1опции недоступны в OSX
Валерий Ван
1

Что насчет этого:

find … | egrep -o -e '[^/]+$'

Преимущество: создается только один дополнительный процесс, а не один для каждого результата.

Дэвид Фёрстер
источник
0

Вы можете позвонить shиз -execопции поиска и избежать использования ненужных каналов. Это также имеет то преимущество, что вам не нужно беспокоиться о смешных именах файлов (пробелы, переводы строки и т. Д.):

find . -type f -exec sh -c 'echo "${0##*/}"' {} \;
evilsoup
источник