While loop quebrando a meio caminho através de arquivo

0

Eu tenho um loop while que pega um arquivo de texto como entrada (uniq.txt) e usa o grep para encontrar duplicatas em outro arquivo (stage.txt) e então grava o número de duplicatas e o conteúdo da linha em outro arquivo, Output.txt.

Por alguma razão, o loop while pára aleatoriamente na metade do arquivo?

while read line; do
            results=$(grep ${line} ./stage.txt | wc -l)
            printf  '%s\n' "$line $results" >> Output.txt
            done < uniq.txt

Aqui é onde está o problema. Meu loop while pára em -b.

apps
archive.
AWACP
awac-pri
-b
backup
bad_file
bak.path
BasicPlu
    
por cdruckemiller 13.09.2017 / 17:47

2 respostas

3

Seu loop é interrompido em -b porque, nesse ponto, ${line} é interpretado como a opção -b to grep . Para evitar que você precise adicionar -- , informe grep para não procurar mais opções:

results=$(grep -- "$line" ./stage.txt | wc -l)
    
por 13.09.2017 / 17:54
1

O problema vem de uma variável que recebe um valor que parece um sinalizador de linha de comando, como Satō Katsura apontou .

No entanto, o que você está fazendo também pode ser feito com

awk 'NR==FNR {p[++i]=$0;next} {for (i in p){if (match($0,p[i])){c[i]++}}} END {for (i in p){print p[i],c[i]}}' uniq.txt stage.txt >output.txt

... se o número de padrões em uniq.txt não estiver na casa dos milhões.

O script awk foi desvendado:

NR==FNR { p[++i] = $0; next     }

        {
            for (i in p) {
                if (match($0, p[i])) {
                    c[i]++
                }
            }
        }

END     {
            for (i in p) {
                print p[i],c[i]
            }
        }

Primeiro, lê cada linha de uniq.txt na matriz p e continua contando (na matriz c ) quantas linhas de entrada do segundo arquivo contém cada padrão em p .

No final, os padrões e as contagens correspondentes são exibidos.

Isso evita um loop de shell lento (executando grep e wc uma vez para cada padrão e também abrindo e gravando em um arquivo de saída muitas vezes) e também evita ter que lidar com padrões de leitura em uma variável shell com read .

Se você deseja fazer uma correspondência de cadeia fixa, ou seja, não tratar as linhas em uniq.txt como padrões de expressão regular, mas como sequências fixas (como em grep -F ), basta alterar a chamada de função match($0, p[i]) para index($0, p[i]) .

    
por 13.09.2017 / 18:48