Seguindo a ideia inicial do @ steeldriver, você pode fazer:
egrep -rl '.*printf.*%s.*bcm_errmsg\(rv\).*' . | xargs -d '\n' sed -i '/printf/ s/%s/%d/; /printf/ s/bcm_errmsg(rv)/rv/'
Eu quero recursivamente encontrar arquivos na minha árvore de origem por conteúdo. Eu tentei o seguinte usando o grep:
$ grep -rn printf | grep %s | grep bcm_errmsg\(rv\)
Isso me retorna todas as linhas que eu queria, mas agora, eu gostaria de obter o nome do arquivo de cada arquivo que corresponde, então eu mudei para:
$ grep -rn printf | grep %s | grep -l bcm_errmsg\(rv\)
mas em vez de imprimir os nomes dos arquivos, eu só obtenho
(standard input)
impresso na stdout. Como faço para corrigir isso para obter cada nome de arquivo & caminho (para usar sed
nele)?
O que eu quero fazer: encontre todos os arquivos com printf
linhas que também contenham %s
e bcm_errmsg(rv)
e aplique o seguinte comando sed aos arquivos encontrados:
sed -i 's/%s/%d/g; s/bcm_errmsg(rv)/rv/g;'
Seguindo a ideia inicial do @ steeldriver, você pode fazer:
egrep -rl '.*printf.*%s.*bcm_errmsg\(rv\).*' . | xargs -d '\n' sed -i '/printf/ s/%s/%d/; /printf/ s/bcm_errmsg(rv)/rv/'
grep -rlZP '(?=.*printf)(?=.*%s)(?=.*bcm_errstr\(rv\))' . |
xargs -r0 sed -i -e '
/%s/!b
/printf/!b
/bcm_errstr(rv)/!b
s/%s/%d/g;s/bcm_errstr(rv)/rv/g
'
Primeiro, executamos um diretório recursivo. a partir do diretório atual que verifica os arquivos que possuem as strings: printf,% s e bcm_errstr (rv) na mesma linha, mas talvez em qualquer ordem. As opções grep
que nos ajudam a fazer isso são:
-r
= > irá recursivamente lançar em todos os arquivos no diretório atual e abaixo. -l
= > irá listar nomes de arquivos que correspondam aos critérios, ou seja, todas as 3 strings na mesma linha. -Z
= > os nomes de arquivos selecionados são nulos separados (\ 0) ao invés da usual nova linha (\ n) para que possamos lidar com qualquer tipo de nome de arquivo. -P
= > habilitar o mecanismo regex Perl, por meio do qual somos capazes de usar lookaheads para determinar se as 3 strings estão presentes na mesma linha. No outro lado do pipe, xargs
está aguardando para receber os nomes dos arquivos, separados por \ 0. Em seguida, ele alimenta todos esses nomes de arquivos, tanto quanto possível, para a linha de comando sed. O comando sed que você já conhece da sua pergunta anterior, onde ele executa os subs. somente nas linhas que contêm os 3 cordões na mesma linha.
Eu acho que você está complicando demais as coisas. Para procurar a string foo
em todos os arquivos localizados no diretório atual e subdiretórios, simplesmente execute
grep -r "foo" *
Por padrão, o grep exibe a linha correspondente precedida pelo nome do arquivo onde foi encontrado.
Em vez disso, o seguinte será apenas o nome do arquivo, sem a linha correspondente:
grep -rl "foo" *