Find and Replace Multiple Words Inside a File

Asked

Viewed 7,992 times

4

I want to develop a script which will replace any words in filing cabinet.

I know what I can do with the command(s) below:

$ tr 'ABC' '123' < arquivo.txt > novo-arquivo.txt

or

$ sed "s/ABC/123/g" arquivo.txt > novo-arquivo.txt

However, I do not only wish to exchange a single "word" for "another", but rather, to make several changes of several "words" within the file(document)

For example:

I would like the script perform substitution in mass .. group/set words that will be defined by the user himself.

Suppose the file(document) contains the following words:

  • man
  • sun
  • day

Then the script should ask the question about the proper exchange, something like that:

1) - Type here all words in which you want to replace them: man, sun, day, day

2) - Now, type in the same previous order, the new ones to be inserted: woman, moon, night

That is, automating change generally, rather than replacing only a single word, may be more than one in different occurrence.

Completion

Then it would be enough to be defined by the user, to make the exchange on itself filing cabinet simultaneously (at once). Change a wordset for others that the user himself can define.

2 answers

3

Test(Requires Terminal/Console - Linux/Unix)

Create a filing cabinet text, with the following content: man, day, sun.

Now, open your console terminal, paste or enter the command below:

for troca in `cat teste.txt`; do echo "$(sed 's/homen/mulher/ ; s/dia/noite/ ; s/sol/lua/' teste.txt)" > teste.txt; $troca; done

Explaining

The Lasso for will pass the coordinates to the command cat "Read file" when invoked to variable $troca, and then "perform action for each line" via sed, at this point, note that I put it sed in an éspecie of subshell involved between parentheses.

The advantage of that is that we don’t need to create a new output file, already updating only the original file.

Finally - I reserved the right to present only one line and only. It is already the main core for the purpose here.

3


To get the words to be replaced from the user input and put in a array, do so:

palavras=()
while IFS= read -r -p "Digite a palavra ([ENTER] para terminar): " linha; do
    [[ $linha ]] || break
    palavras+=("$linha")
done

Assuming you have the arrays of words to be replaced and substitutes:

substituir=( "homem" "sol" "dia" )
substituto=( "mulher" "lua" "noite" )

Use a bow tie for to iterate on one of arrays, and with the sed you make the replacement:

for ((i=0; i<${#substituir[@]}; ++i)); do
    printf "Substituindo ${substituir[i]} por ${substituto[i]}...\n"

    sed -i "s/${substituir[i]}/${substituto[i]}/" foo.txt
done

See DEMO

Note: If you need the replacement to be done globally, add the modifier g after the second delimiter.

It is also possible to use Perl in a row:

perl -i -pe 's/homem/mulher/g; s/sol/lua/g; s/dia/noite/g' foo.txt 

The option i basically indicates that changes will be made to the file. p is used to iterate over the file, e indicates the code to be executed, in this case s/.../.... More information.

  • 1

    With sed you can also use a line: sed -i -e’s/.... /.../; s/.../.../;...'

Browser other questions tagged

You are not signed in. Login or sign up in order to post.