Как мне выполнить find с GNU xargs для обхода набора каталогов?

656
wilhelmtell
$ echo .h d e.h |xargs -IA find A -name '*.h' find: `a.h b.h c.h d e.h': No such file or directory $ echo -e a.h\\nb.h c.h d e.h |xargs -IA find A -name '*.h' a.h find: `b.h c.h d e.h': No such file or directory 

Проблема в том, что -Ixargs будет предполагать, что аргументы ограничены символом новой строки. Я не уверен, почему это так. Я считаю, что могу решить эту проблему с помощью sed, но мне интересно, есть ли хитрость xargs или идиома, с которыми я не знаком, которые люди используют для решения этой проблемы.

Я ищу решение, которое также будет работать в OS X. В OS X ключ xargs -J, кажется, работает нормально. На man-странице утверждается, что этот переключатель будет просто контролировать расположение аргументов для исполняемого файла - именно это я и хочу.

0

4 ответа на вопрос

0
quack quixote

Хм. Тебе нужна труба и ксаргс? Кажется, что все, что нужно вашему примеру, - это findи echo.

Я предполагаю, что это кусок большей головоломки, поэтому это может не сработать в контексте того, что вы делаете, но ваш пример может быть записан так:

$ find `echo .h d e.h` -name '*.h'  $ find $(echo .h d e.h) -name '*.h' 

... что в моей системе приводит к findпроверке каждого аргумента в отдельности:

find: `a.h': No such file or directory find: `b.h': No such file or directory find: `c.h': No such file or directory find: `d': No such file or directory find: `e.h': No such file or directory 

У меня нет машины OSX для тестирования, и это может быть связано с Bash.

Моим первоначальным намерением было получить список каталогов и файлов, поступающих из stdin. Я должен сделать с одним из обходных путей. Мне все еще любопытно, почему - я подразумеваю разграничение с помощью новой строки. wilhelmtell 14 лет назад 0
дайте время, у кого-то еще может быть реальный ответ для вас. Я подумал, может быть, вам нужно расширение, а не STDIN. quack quixote 14 лет назад 0
0
Ryan Thompson

Почему не просто find .h d e.h -name '*.h'?

см. его комментарий к моему ответу; ему нужен список аргументов от stdin. (хорошее упрощение моего ответа, по крайней мере, в примере `find` +` echo`.) quack quixote 14 лет назад 0
Хорошо, если вам нужен список, поступающий из stdin, вы должны попытаться сделать одно из следующего: 1. Не используйте пробелы в именах каталогов, а затем передавайте данные через `sed -e 's / \ s + / \ n / g'`; 2. Найдите способ разделить входящие имена каталогов по символам новой строки или нулям, а затем используйте «xargs --null find ...» или «при чтении x; делать ... ; done`. Ryan Thompson 14 лет назад 0
0
user23307

вы пробовали опцию -d для xargs?

justin@eee:~$ echo .h d e.h |xargs -d ' ' -n1 -IA echo foo A foo a.h foo b.h foo c.h foo d foo e.h 

или даже проще,

justin@eee:~$ for x in $(echo .h d e.h);do echo foo $x;done foo a.h foo b.h foo c.h foo d foo e.h 
`-I` подразумевает игнорирование` -d`. Кроме того, `-d` принимает в качестве аргумента ровно один символ. Вы не можете иметь произвольный пробел в качестве разделителя. То есть с точки зрения регулярных выражений это / /, но вы не можете сделать / \ s / или даже / \ s + /. wilhelmtell 14 лет назад 0
отлично работает для меня, см. мой комментарий. Если это по-прежнему не то, что вы хотите, вам нужно будет привести лучший пример, который показывает, что вы действительно пытаетесь сделать. user23307 14 лет назад 0
0
Ole Tange

Используйте GNU Parallel:

parallel -q find {} -name '*.h' ::: .h d e.h 

Посмотрите вступительное видео, чтобы узнать больше: http://www.youtube.com/watch?v=OpaiGYxkSuQ

Похожие вопросы