10

Я пытался найти все файлы определенного типа, распределенные в подкаталогах, и для моих целей мне нужно было только имя файла. Я попытался удалить компонент пути через basename , но он не работал с xargs:

$ find . -name '*.deb' -print | xargs basename 
basename: extra operand `./pool/main/a/aalib/libaa1_1.4p5-37+b1_i386.deb'
Try `basename --help' for more information.

Я получаю то же самое (точно такую же ошибку) с любым из этих вариантов:

$ find . -name '*.deb' -print0 | xargs -0 basename 
$ find . -name '*.deb' -print | xargs basename {}

Это, с другой стороны, работает как ожидалось:

$ find . -name '*.deb' -exec basename {} \;
foo
bar
baz

Это происходит в современных Cygwin и Debian 5.0.3. Мой диагноз состоит в том, что xargs по какой-то причине передает две строки ввода в basename, но почему? Что тут происходит?

4 ответа4

22

Потому что basename хочет только один параметр ... не много. И xargs создает много параметров.

Чтобы решить вашу реальную проблему (перечислите только имена файлов):

 find . -name '*.deb' -printf "%f\n"

Который печатает только «базовое имя» (человек найти):

 %f     File's name with any leading directories
        removed (only the last element).
17

Попробуй это:

find . -name '*.deb' | xargs -n1 basename
4

Базовое имя принимает только один аргумент. Использование -exec работает правильно, потому что каждый {} заменяется текущим обрабатываемым именем файла, и команда запускается один раз для соответствующего файла, вместо того, чтобы пытаться отправить все аргументы в basename за один раз.

2

xargs может быть вынужден передать только один аргумент ...

find . -name '*.deb' -print | xargs -n1 basename

Это работает, однако принятый ответ использует find более подходящим способом. Я нашел этот вопрос при поиске проблем с xargs basename как я использую другую команду для получения списка расположений файлов. Флаг -n1 для xargs был для меня окончательным ответом.

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .