Classificando diretórios pesquisando uma determinada extensão de arquivo

1

Digamos que eu esteja em um diretório A, em A há muitas pastas (B, C, D, etc.) e em cada pasta há um arquivo "* .out" e subpastas. Eu quero executar um script de um que irá procurar o texto "index123" no arquivo * .out e imprimir todos os nomes de pasta correspondentes.

Aqui está o meu sript:

#!/bin/sh  
FILES=home/A  
grep --include=\*.out -rnw $FILES -e "index123" | while read file; do  
str1="FILES/$(basename $file)"  
echo $str1
done

Isso mostra erro.

N.B. Isso pode ser feito por "encontrar" em um código de linha, mas por que loop while mostrado mostra erro?

    
por Akand 11.04.2018 / 20:59

2 respostas

1

De acordo com a postagem encontre um arquivo por meio de busca particular em while loop uma das soluções pode ser como segue usando o while loop:

#!/bin/bash
while IFS= read -r d;
grep -q "index123" "$d" && dirname "$d"|awk -F'/' '{print $2}'
done < <(find . -maxdepth 2 -type f -name "*.out")

    
por 20.07.2018 / 17:45
2

Assumindo uma estrutura de diretório como a seguinte:

A
|-- B
|   |-- file1.out
|   |-- file2.out
|   '-- file3.out
|-- C
|   |-- file1.out
|   |-- file2.out
|   '-- file3.out
|-- D
|   |-- file1.out
|   |-- file2.out
|   '-- file3.out
'-- E
    |-- file1.out
    |-- file2.out
    '-- file3.out

O problema com seu código é que seu grep produzirá uma saída parecida com

./B/file1.out:2:some data which includes the word index123
./B/file2.out:2:some data which includes the word index123
./B/file3.out:2:some data which includes the word index123
./C/file1.out:2:some data which includes the word index123
./C/file2.out:2:some data which includes the word index123
./C/file3.out:2:some data which includes the word index123
./D/file1.out:2:some data which includes the word index123
./D/file2.out:2:some data which includes the word index123
./D/file3.out:2:some data which includes the word index123
./E/file1.out:2:some data which includes the word index123
./E/file2.out:2:some data which includes the word index123
./E/file3.out:2:some data which includes the word index123

Essa é a saída de

grep --include=\*.out -rnw . -e "index123"

com A como o diretório atual.

Você então tentará executar basename nessas linhas individuais, o que falhará, pois basename leva no máximo dois argumentos (um pathame e um sufixo para remover esse nome de caminho). O GNU basename irá reclamar sobre um "operando extra" enquanto o BSD basename irá reclamar sobre o uso incorreto.

grep mostrar-lhe-á os nomes dos ficheiros (apenas, ou seja, não a linha completa correspondente) quando a utilizar com o sinal -l .

Isso significa que seu script pode ser substituído pelo único comando

grep -w -l "index123" */*.out

Isso fornecerá a saída no formulário

B/file1.out
B/file2.out
B/file3.out
C/file1.out
C/file2.out
C/file3.out
D/file1.out
D/file2.out
D/file3.out
E/file1.out
E/file2.out
E/file3.out

Eu adicionei -w como você usou na sua linha de comando grep . -n (para linhas de numeração, que você também está usando) não pode ser usado junto com -l .

A julgar pelo seu código, é isso que você quer.

Se você precisa apenas dos nomes das pastas, faça

$ grep -w -l "index123" */*.out | sed 's#/[^/]*##' | sort -u
B
C
D
E

Tudo isso pressupõe que A é o diretório de trabalho atual, mas você disse que esse era o caso na pergunta, então não deveria ser um problema.

    
por 11.04.2018 / 22:20