Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to add characters in word and replace it using sed command in linux

Tags:

linux

bash

sed

awk

I have one requirement.

I have one text file named as a.txt, which is having list of words -

GOOGLE
FACEBBOK

Now I have one another file named as b.txt , which is having content as

Company name is google.
Company name is facebook.

Like this n of lines are there with different different words.

Then I am writing script file -

    FILENAME="a.txt"

SCHEMA=$(cat $FILENAME)

for L in $SCHEMA
do
    echo "${L,,}"

sed -i -E "s/.+/\L&_/" b.txt
done

So after running script the output file of b.txt file I am expecting is

 Company name is google_
 Company name is facebook_

But the output after running that script I am getting is -

Company name is google.__
Company name is facebook.__

And this output will be saved in b.txt file as I mentioned in sed command

Note - In a.txt I am having the list of Words which I want to replace and in b.txt file I am having paragraphs of line in which I am having words like google. , facebook. and so on.

So that's why I am not able to give direct sed command for replacement.

I hope that you understand my requirement.

Thanks in advance!

like image 770
saurabh704 Avatar asked Dec 02 '25 11:12

saurabh704


2 Answers

You can use the following GNU sed solution:

FILENAME="a.txt"
while IFS= read -r L; do
  sed -i "s/\($L\)\./\1_/gI" b.txt
done < $FILENAME

Or, the same without a loop as a single line (as used in anubhava's answer):

sed -i -f <(printf 's/\\(%s\\)\\./\\1_/gI\n' $(<"$FILENAME")) b.txt

With the script, you

  • while IFS= read -r L; do - read the file line by line, each line being assigned to L
  • sed -i "s/\($L\)\./\1_/gI" b.txt - replaces all occurrences of L (captured into Group 1 with the help of capturing \(...\) parentheses) followed with . (in a case insensitive way due to I flag) in b.txt with the same value as captured in Group 1 and _ appended to it.
  • -f allows passing a list of commands to sed
  • printf 's/\\(%s\\)\\./\\1_/gI\n' $(<"$FILENAME") creates a list of sed commands, in this case, it looks like
s/\(GOOGLE\)\./\1_/gI
s/\(FACEBOOK\)\./\1_/gI
like image 187
Wiktor Stribiżew Avatar answered Dec 04 '25 00:12

Wiktor Stribiżew


Here is how you can do it in a single shell command without any loop using gnu-sed with printf in a process substitution:

sed -i -E -f <(printf 's/\\b(%s)\\./\\1_/I\n' $(<a.txt)) b.txt

cat b.txt
Company name is google_
Company name is facebook_

This would be far more efficient than running sed or awk in a loop esp if input files are big in size.

  • printf command is creating a sed command script that looks like this:
s/\b(GOOGLE)\./\1_/I
s/\b(FACEBOOK)\./\1_/I
  • sed -f runs that dynamically generated script
like image 45
anubhava Avatar answered Dec 04 '25 01:12

anubhava



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!