Encontre arquivos que contenham palavras-chave e mostre apenas o caminho do arquivo e o número da linha

3

Gostaria de encontrar todos os arquivos Java contendo a palavra-chave File.createTempFile com o número da linha. Aqui está o que eu fiz:

$ find . -name "*.java" | xargs grep -n "File.createTempFile"
./nuxeo-studio-test/src/test/java/com/nuxeo/studio/web/StudioServletTest.java:162:            File tmpFile = File.createTempFile(jarEntryName, null, Environment.getDefault().getTemp());
./nuxeo-studio-ui/src/main/java/com/nuxeo/studio/core/builders/WorkflowFeatureBuilder.java:421:            tmp = File.createTempFile(".workflow-to-zip", ".tmp", workspace.getRoot());
./nuxeo-studio-ui/src/test/java/com/nuxeo/studio/core/backup/TestS3Backup.java:101:        File tempFile = File.createTempFile(RandomStringUtils.randomAlphabetic(5), ".tmp");
./nuxeo-studio-ui/target/classes/com/nuxeo/studio/core/builders/WorkflowFeatureBuilder.java:421:            tmp = File.createTempFile(".workflow-to-zip", ".tmp", workspace.getRoot());
./nuxeo-studio-web/src/main/java/com/nuxeo/studio/web/v1/ProjectResource.java:191:            File zip = File.createTempFile(filename + "-", ".zip", tempRepo);

No entanto, achei esse resultado muito longo para ser lido. Gostaria de manter apenas o caminho do arquivo e o número da linha. Aqui está o resultado esperado:

./nuxeo-studio-test/src/test/java/com/nuxeo/studio/web/StudioServletTest.java:162
./nuxeo-studio-ui/src/main/java/com/nuxeo/studio/core/builders/WorkflowFeatureBuilder.java:421
./nuxeo-studio-ui/src/test/java/com/nuxeo/studio/core/backup/TestS3Backup.java:101
./nuxeo-studio-ui/target/classes/com/nuxeo/studio/core/builders/WorkflowFeatureBuilder.java:421
./nuxeo-studio-web/src/main/java/com/nuxeo/studio/web/v1/ProjectResource.java:191

Alguém poderia me ensinar como fazer isso?

    
por Mincong Huang 13.03.2017 / 15:25

5 respostas

2

Aqui está uma maneira com awk :

find . -name '*.java' -exec awk '/PATTERN/{print FILENAME,FNR}' {} +

ou, se você quiser emular a saída de grep :

find . -name '*.java' -exec awk '/PATTERN/{printf("%s:%s\n", FILENAME, FNR)}' {} +
    
por 13.03.2017 / 15:41
3

Com pcregrep , você poderia fazer:

pcregrep --include='\.java$' -rHno1 '()File\.createTempFile' .

A saída será parecida com:

./path/to/file.java:12:

Se o padrão aparecer mais de uma vez em uma linha, haverá tantas saídas de linhas. Se você não quiser, pode alterá-lo para:

pcregrep --include='\.java$' -rHno1 '^().*?File\.createTempFile' .
    
por 13.03.2017 / 17:43
2
keyW='File.createTempFile'
find . -type f -name '*.java' -exec perl -slne '
  print "$ARGV:$." if /\Q$k\E/; $. = 0 if eof;
' -- -k="$keyW" -- {} +
    
por 13.03.2017 / 15:48
1

Basta filtrar a parte que você não quer:

grep -n … | cut -d : -f 1,2

(Isto assume que os nomes dos seus arquivos não contêm dois pontos ou novas linhas.)

    
por 14.03.2017 / 02:35
1
esport keyW='File.createTempFile'
find . -name '*.java' -type f -exec sh -c '
   grep -hn "$keyW" "$1" | cut -d":" -f1 |
   while IFS=: read -r n x; do
      printf "%s:%s\n" "$1" "$n"
   done
' {} {} \;

Notas:

grep tem que ser executado 1 / por arquivo é a limiação para este método.

    
por 13.03.2017 / 17:17