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


13

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

Ответы:


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

Это сломает файлы с пробелами в их именах (см. Парсинг 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

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##*/}"' {} \;
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.