LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Linux - General (https://www.linuxquestions.org/questions/linux-general-1/)
-   -   bash : (find + grep + sed) to edit only some of matching occurrences (https://www.linuxquestions.org/questions/linux-general-1/bash-find-grep-sed-to-edit-only-some-of-matching-occurrences-4175650951/)

dezix 03-26-2019 06:46 PM

bash : (find + grep + sed) to edit only some of matching occurrences
 
Hi!

In a <path> (directory) containing some <file>.txt
them self containing lines like:

Code:

<chain1><something else>
If I use the following command:

Code:

find <path> -type f -name "*.txt" -exec sed -i 's/<chain1>/<chain2>/g' '{}' \;
every:

Code:

<chain1><something else>
will be changed to:

Code:

<chain2><something else>

But what I really want, is only to change :

Code:

<chain1><something else containing <chain3> >
in:

Code:

<chain2><something else containing <chain3> >

Is there some way to insert a
Code:

grep <chain3>
in the general command above to get this result?


Thanks for help!

berndbausch 03-26-2019 09:16 PM

Quote:

Originally Posted by dezix (Post 5978124)
But what I really want, is only to change :
Code:

<chain1><something else containing <chain3> >
in:
Code:

<chain2><something else containing <chain3> >

sed has grep built-in, so to speak.

I am lazy and assume that <chain1> always occurs before <chain3> in a line.
Code:

sed '/<chain3>/s/<chain1>/<chain2>/'
This performs the replacement in all lines that contain the string <chain3>. Strictly speaking, this is not quite what you ask for, but as long as my assumption is correct, it does the job.

OK, here is a more water-tight way to do it:
Code:

sed '/<chain1>.*<chain3>/s/<chain1>/<chain2>/'
Here, the replacement is made in lines that contain <chain1> followed by any string (including the empty string) followed by <chain3>.

BW-userx 03-26-2019 09:47 PM

maybe in a script due to if else clause. if you're doing simple name changing.
Code:

#!/bin/bash
working_dir-/whatever/it/is

chain1=
chain2=
chain3=
while read s
do

 if [[ "$s" =~ "$chain1" ]] ;
then
      mv "$s" "${s/chain1/chain2}"
else
      mv "$s" "${s/"$chain3"}"
fi
done <<<"$(find "$working_dir" -type f -name "*.txt")"

if you are doing text within a file then that water-tight one above, try that.

dezix 03-27-2019 04:59 AM

@berndbausch

Your first "lazy" proposal works perfectly :))

sed is a very usefull piece of code

I thank you!


@BW-userx
Effectively I was wondering myself if this action require some logical/conditional statement to be achieved
But I still don't know how to do that :((

I've tried a few around your example script,
but that doesn't work.

What I don't understand is why to use mv,
my intention is to modify the files content not there names.

I thank you too for the trail

For me the subject is solved :))

BW-userx 03-27-2019 07:03 AM

Quote:

Originally Posted by dezix (Post 5978251)
@berndbausch

Your first "lazy" proposal works perfectly :))

sed is a very usefull piece of code

I thank you!


@BW-userx
Effectively I was wondering myself if this action require some logical/conditional statement to be achieved
But I still don't know how to do that :((

I've tried a few around your example script,
but that doesn't work.

What I don't understand is why to use mv,
my intention is to modify the files content not there names.

I thank you too for the trail

For me the subject is solved :))

I wasn't fully understanding what you are trying to do at the time, as state for a simple name change of the files name. the sed command fixes text within a file. with sed you'd have to set it up to search both conditions if one is found it changes that, if the other is found then it changes that instead, without the use of if else.


All times are GMT -5. The time now is 01:01 AM.