Eu tenho um arquivo, digamos map.txt
, contendo uma lista de strings de pesquisa e substituições correspondentes:
search -> replacement
bigBone -> bb
fishMarket -> fm
dogCollar -> dc
...
Preciso realizar a pesquisa e substituição de todas as strings correspondentes aos itens acima para todos os arquivos recursivamente em uma pasta, exceto links simbólicos. Eu sei como fazer um de cada vez assim:
$ find /some/folder -type f -exec sed -i 's/old_text/new_text/g' {} \;
Como posso fazer isso em grande escala usando o mapeamento acima? eu liessa questão, mas não entendi direito.
Responder1
Responder
Se você não está preocupado com a velocidade (esta é uma tarefa única), talvez você possa tentar isto:
cat map.txt | while read line; do
neww=${line##* };
oldw=${line%% *};
find /some/folder -type f -exec sed -i "s/$oldw/$neww/g" {} \;
done
Não é o ideal, eu sei... :-P
PS: verifique em uma pasta de teste para ver se funciona!
Explicação
Basicamente:
- Arquivo gato map.txt.
- Leia cada linha e obtenha a palavra a ser substituída
$oldw
e a substituição$neww
. - Para cada par, execute o comando find que você já estava usando (observe as aspas duplas desta vez para permitir a substituição de variáveis).
Sobre expansão de parâmetros
Para definir as variáveis $oldw
temos $neww
que obter a primeira e a última palavra de cada linha. Para fazer isso, estamos usando expansão de parâmetros (implementação pura do Bash), embora pudéssemos ter usado outras formas de obter a primeira e a última palavra da string (ou seja, cut
ou awk
).
${line##* }
: da variávelline
, remova o padrão de prefixo maior (double#
), onde padrão é qualquer caractere (*
) seguido por um espaço (). Então damos a última palavra
line
.${line%% *}
: da variávelline
, remova o maior padrão de sufixo (duplo%
), onde padrão é um espaço () seguido por quaisquer caracteres (
*
). Então colocamos a primeira palavra emline
.
As palavras foram separadas por um espaço neste caso, mas poderíamos ter usado qualquer separador.
Responder2
Às vezes preciso pesquisar e substituir termos nos arquivos de configuração.
Eu escrevi um script disponível no githubsandr - pesquise e substituaque permite criar/utilizar um mapa e realizar substituições em arquivos.
Um exemplo de uso:
$ cat file
Voyez ce jeu exquis wallon, de graphie en kit mais bref. Portez ce vieux whisky au juge blond qui fume sur son île intérieure, à côté de l'alcôve ovoïde, où les bûches se consument dans l'âtre, ce qui lui permet de penser à la cænogenèse de l'être dont il est question dans la cause ambiguë entendue à Moÿ, dans un capharnaüm qui, pense-t-il, diminue çà et là la qualité de son œuvre. Prouvez, beau j
$ cat map.txt
wallon => WALLON
se => SE
penser => PENSER
beau => BEAU
$ cat file | ./sandr -a map.txt
Voyez ce jeu exquis WALLON, de graphie en kit mais bref. Portez ce vieux whisky au juge blond qui fume sur son île intérieure, à côté de l'alcôve ovoïde, où les bûches SE consument dans l'âtre, ce qui lui permet de PENSER à la cænogenèSE de l'être dont il est question dans la cauSE ambiguë entendue à Moÿ, dans un capharnaüm qui, penSE-t-il, diminue çà et là la qualité de son œuvre. Prouvez, BEAU j