Só para mostrar que você pode fazer isso sem precisar da ajuda de find
. Você pode usar a capacidade de grep
para reciclar o sistema de arquivos também. Supondo que sua versão de grep
tenha a opção -R
:
$ grep -R version | awk -F: '/CMake.*:/ {print $1}'
Exemplo
Eu criei alguns dados de amostra que incluíam arquivos chamados CMake1-3 que continham a string version
, assim como um arquivo chamado CMake0 que não continha. Eu também criei 2 arquivos chamados afile
que também continham a string version
.
$ tree .
.
|-- CMake1
|-- dir1
| |-- dirA1
| | '-- CMake1
| |-- dirA2
| '-- dirA3
|-- dir2
| |-- dirA1
| | '-- CMake0
| |-- dirA2
| | |-- afile
| | '-- CMake2
| '-- dirA3
'-- dir3
|-- dirA1
|-- dirA2
| '-- afile
'-- dirA3
'-- CMake3
Agora, quando eu executo o comando acima:
$ grep -R version | awk -F: '/CMake.*:/ {print $1}'
CMake1
dir2/dirA2/CMake2
dir3/dirA3/CMake3
dir1/dirA1/CMake1
Detalhes
Os comandos acima produzem uma lista como esta em grep
:
$ grep -R version
CMake1:version
dir2/dirA2/CMake2:version
dir2/dirA2/afile:version
dir3/dirA2/afile:version
dir3/dirA3/CMake3:version
dir1/dirA1/CMake1:version
E awk
é usado para localizar todas as cadeias que contêm CMake.*:
e para dividir essas cadeias em dois pontos ( :
) e para retornar apenas o primeiro campo dessa divisão, ou seja, o caminho da variável nome de um arquivo CMake*
correspondente.
2 grep's + PCRE
Versões mais modernas do grep geralmente incluem o que é chamado de PCRE - Perl Compatible Exprssions Compatible . Assim, você poderia usar 2 grep
de comandos, com o segundo usando PCRE para extrair apenas a parte do caminho do arquivo, omitindo o :version
da string do primeiro grep
.
Exemplo
$ grep -R version | grep -Po '.*CMake.*(?=:version)'
CMake1
dir2/dirA2/CMake2
dir3/dirA3/CMake3
dir1/dirA1/CMake1
O -o
retornará apenas a parte correspondente, enquanto -P
é o que habilita o PCRE. Dentro da expressão regular, estamos usando um lookahead, ( ?=...
), no final, para selecionar apenas strings que têm um :version
à direita. Essa visão é apenas para ajudar a alinhar nosso padrão, ele não é incluído nos resultados que retornamos nem é parte do padrão real que estamos buscando, ou seja, CMake.*
.
Números de linha
Você também pode incluir a opção -n
no primeiro grep
, para que o número da linha em que a string version
foi encontrada também possa ser incluído na saída.
Exemplo
$ grep -Rn version | grep -Po '.*CMake.*(?=:version)'
CMake1:1
dir2/dirA2/CMake2:9
dir3/dirA3/CMake3:1
dir1/dirA1/CMake1:1
Para que o primeiro exemplo funcione, você precisa alterar os comandos awk
:
$ grep -Rn version | awk -F: '/CMake.*:/ {print $1":"$2}'
CMake1:1
dir2/dirA2/CMake2:9
dir3/dirA3/CMake3:1
dir1/dirA1/CMake1:1
O primeiro exemplo dá a você a oportunidade de mover o número da linha, já que já analisamos em um campo separado via awk
.
Exemplo
Aqui podemos colocar o número primeiro.
$ grep -Rn version | awk -F: '/CMake.*:/ {print $2":"$1}'
1:CMake1
9:dir2/dirA2/CMake2
1:dir3/dirA3/CMake3
1:dir1/dirA1/CMake1