Retorna a contagem de correspondências com localizar / substituir usando sed

3

Estou tentando obter uma contagem do número de strings substituídas com find e sed .

O que eu estou começando:

# find . -name \*.php -exec sed -i -e "s|finddddd|replaceeeee|g" {} \;

Isso substitui quatro correspondências de "finddddd". Depois de executar este comando, redefino meu arquivo de teste para que o comando funcione novamente.

Eu tentei usar wc -l , O comando encontrado e substituído para instâncias de "findddd", mas mostra 0 correspondências encontradas na linha abaixo.

# find . -name \*.php -exec sed -i -e "s|finddddd|replaceeeee|g" {} \; | wc -l
0

Também tentei mover wc -l no comando, mas recebo erros.

find . -name \*.php -exec sed -i -e "s|finddddd|replaceeeee|g" {}| wc -l;
find: missing argument to '-exec'
0

e

find . -name \*.php -exec sed -i -e "s|finddddd|replaceeeee|g" | wc -l {} \;
wc: {}: No such file or directory
wc: ;: No such file or directory
0 total
find: missing argument to '-exec'

Como obtenho o comando base para gerar a contagem de correspondências?

    
por a coder 30.10.2014 / 19:57

1 resposta

3

Você está usando a ferramenta errada. wc contará linhas de entrada, mas como você está usando sed -i , não há linhas impressas, então nada para wc contará. Mesmo sem isso, o comando sed teria imprimido todas as linhas do arquivo para que ainda não funcionasse corretamente. Aqui está uma abordagem diferente:

  1. Use perl ao invés

    find . -name \*.php \
      -exec perl -i -lpe 's|finddddd|replaceeeee|g && print STDERR "."' {} \;  \
    2>&1 | wc -l
    

    O truque é imprimir um . cada vez que um substituto for bem-sucedido e passar os resultados por wc . O -i flag edita o arquivo no local e o -l faz com que uma nova linha seja adicionada a cada chamada de print . O -p diz ao perl para imprimir cada linha de entrada depois de aplicar o script passado por -e . Como estamos editando o arquivo, precisamos imprimir em STDERR para evitar que o . seja adicionado ao arquivo. O STDERR é então redirecionado para STDOUT ( 2>&1 ), o que nos permite usar wc .

  2. Se você precisar contar várias substituições na mesma linha separadamente, use perl novamente:

    find . -name \*.php -exec \
        perl -i -lpe '$l++ while s|finddddd|replaceeeee|; 
        END{print STDERR $l}' {} + 2>&1 
    

    Aqui, o próprio perl está fazendo a contagem. Observe que usei + em vez de \; para finalizar a chamada -exec . Isso significa que ele tentará combinar os comandos com o mínimo possível. Se você não tiver muitos arquivos .php , todos eles serão passados para uma única execução de perl e o número estará correto. Se você tiver muitos arquivos, isso falhará e você deverá usar isso:

    find . -name \*.php -exec \
      perl -lpe '$l++ while s|finddddd|replaceeeee|; 
                 END{print STDERR $l}' {} + 2>&1 >/dev/null | 
      awk '{k+=$1; }END{print k}'
    
por 30.10.2014 / 20:24