I have two files, fileA with a list of name :
AAAAA
BBBBB
CCCCC
DDDDD
and another fileB with another list :
111
222
333
444
and a third fileC with some text :
Hello AAAAA toto BBBBB dear "AAAAA" trird BBBBBB tuizf AAAAA dfdsf CCCCC
So I need to find and replace every pattern of fileA in fileC by fileB pattern. It works ! But i realised that fileC contains words like "AAAAA" and it isn't replace by "111".
I'm doing this but it doesn't seems to work.
#! /bin/bash
while IFS= read -r lineA && IFS= read -r lineB <&3; do
sed -i -e "s/$lineA/$lineB/g" fileC
done <fileA 3<fileB
Find and replace text within a file using sed command Use Stream EDitor (sed) as follows: sed -i 's/old-text/new-text/g' input.txt. The s is the substitute command of sed for find and replace. It tells sed to find all occurrences of 'old-text' and replace with 'new-text' in a file named input.txt.
Given a list of strings words and a string pattern , return a list of words[i] that match pattern . You may return the answer in any order. A word matches the pattern if there exists a permutation of letters p so that after replacing every letter x in the pattern with p(x) , we get the desired word.
Another option would be to just use perl with globstar. Enabling shopt -s globstar in your . bashrc (or wherever) allows the ** glob pattern to match all sub-directories and files recursively. Thus using perl -pXe 's/SEARCH/REPLACE/g' -i ** will recursively replace SEARCH with REPLACE .
To perform multiple replacements in each element of string , pass a named vector ( c(pattern1 = replacement1) ) to str_replace_all . Alternatively, pass a function to replacement : it will be called once for each match and its return value will be used to replace the match.
This is a good job for GNU awk
:
$ cat replace.awk
FILENAME=="filea" {
a[FNR]=$0
next
}
FILENAME=="fileb" {
b[a[FNR]]=$0
next
}
{
for (i=1;i<=NF;i++) {
printf "%s%s",(b[$i]?b[$i]:$i),(i==NF?RS:FS)
}
}
Demo:
$ awk -f replace.awk filea fileb filec
Hello 111 toto 222 dear 111 trird BBBBBB tuizf 111 dfdsf 333
A solution for sehe:
FILENAME==ARGV[1] { # Read the first file passed in
find[FNR]=$0 # Create a hash of words to replace
next # Get the next line in the current file
}
FILENAME==ARGV[2] { # Read the second file passed in
replace[find[FNR]]=$0 # Hash find words by the words to replace them
next # Get the next line in the current file
}
{ # Read any other file passed in (i.e third)
for (i=1;i<=NF;i++) { # Loop over all field & do replacement if needed
printf "%s%s",(replace[$i]?replace[$i]:$i),(i==NF?RS:FS)
}
}
For replacements the ignore word boundaries:
$ cat replace.awk
FILENAME==ARGV[1] {
find[FNR]=$0
next
}
FILENAME==ARGV[2] {
replace[find[FNR]]=$0
next
}
{
for (word in find)
gsub(find[word],replace[find[word]])
print
}
Demo:
$ awk -f replace.awk filea fileb filec
Hello 111 toto 222 dear "111" trird 222B tuizf 111 dfdsf 333
sed 's/.*/s/' fileA | paste -d/ - fileA fileB | sed 's/$/\//' | sed -f - fileC
and the correct and faster version would be
paste -d/ fileA fileB | sed 's/^/s\//;s/$/\/g/' | sed -f - fileC
A two-phase rocket:
sed -e "$(paste file[AB] | sed 's/\(.*\)\t\(.*\)/s\/\1\/\2\/g;/')" fileC
What this does is create an adhoc sed script using paste file[AB] | sed 's/\(.*\)\t\(.*\)/s\/\1\/\2\/g;/'
:
s/AAAAA/111/g;
s/BBBBB/222/g;
s/CCCCC/333/g;
s/DDDDD/444/g;
And then runs it with fileC
as the input
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With