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