Estou pesquisando arquivos com base em uma expressão regular e, em seguida, tentando pesquisar conteúdo nesses arquivos. Então, por exemplo, eu tenho algo como
#Find all C++ files that match a certain pattern and then search them
find . -name "*.cpp" | grep "<name regex>" | xargs grep "<content regex>"
O problema que estou enfrentando é que alguns dos caminhos têm espaços neles, o que confunde xargs
. Eu sei que, se eu estivesse usando find
, poderia usar o -print0
argumento (junto com o -0
argumento xargs
) para impedir que os xargs tratem os espaços como delimitadores. Existe algo semelhante com grep
?
Ou estou abordando esse problema de maneira totalmente errada? Ingenuamente, find
que grep
a xargs grep
faz sentido para mim, mas estou aberto a outras abordagens que produzem os mesmos resultados.
xargs
usando o-i
parâmetro à lacat sample.txt | grep "pat t ern" | xargs -i grep "{}"
- os chavetas indicam onde posicionar o argumento. O manual me diz que isso-i
foi preterido em favor,-I
então talvez valha a pena dar uma olhada nisso também.Respostas:
Use algo assim, talvez (se gnu grep).
homem grep
Veja também as opções para delimitadores nulos.
fonte
grep -r include='*.cpp'
é um shell glob - e o mesmo acontece com o recurso alinhado w /find . -name '*.cpp' -exec grep -e 'content_pattern' -- {} \;
not w /find . -name '*.cpp' | grep 'name_pattern' | xargs grep 'content_pattern'
Se você precisar pular muitos obstáculos, a eficiência do xargs será perdida de qualquer maneira. Aqui está um trabalho bruto:
Sempre que encontro problemas com espaços nos nomes de arquivos, a resposta é aspas duplas em uma variável.
fonte
Use
find
para fazer toda a filtragem de nome de arquivo. Ao invés deFaz
Se você quiser fazer algo um pouco mais complicado, como
você pode fazer
Observe que eles devem funcionar mesmo para arquivos com novas linhas em seus nomes.
E, se você precisar do poder de expressões regulares completas, poderá usar
-regex
.fonte
Isso deve funcionar mesmo sem as ferramentas GNU:
A
perl
chamada substitui quebras de linha por caracteres nulos, o que permitiráxargs -0
interpretar a entrada por linha e não por espaço em branco.Usando o GNU, você pode remover a
perl
chamada e mudarxargs -0 …
paraxargs -d "\n" …
Não tem
perl
ou GNU? Tente emawk '{printf "%s%c", $0, 0}'
vez disso.fonte
xargs -d "\n"
. Essa é uma ocorrência muito incomum, mas se você não tiver controle dos dados e estiver preocupado com o risco de segurança, tenha cuidado com as expectativas de saída.