LinuxQuestions.org
Share your knowledge at the LQ Wiki.
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 09-01-2019, 05:36 PM   #1
dr.x
Member
 
Registered: Jan 2013
Posts: 195

Rep: Reputation: Disabled
loop replace specific lines from a file with lines from another file .


Hello Folks ,

i will have A file has values X
i will have B file has values Y
######################

Y is always has more lines that X lines .
but i will need to replace the Y lines with X selected lines .

let me give an ex :
X has :
1.1.1.1:1111
2.2.2.2:2222
7.7.7.7:7777
9.9.9.9:9999


Y has :
0.0.0.0:0000
f.f.f.f:ffff
q.q.q.q:qqqq
r.r.r.r:rrrr
u.u.u.u:uuuu
t.t.t.t:tttt
99.99.99.99:9999
w.w.w.w:wwww
qe.qe.qe.qe:qeee
s.s.s.s:ssss
67.67.67.67:676767


now from Y i have feedback that i need to replace the lines :
f.f.f.f:ffff with --> 1.1.1.1:1111
u.u.u.u:uuuu ---> 2.2.2.2:2222
w.w.w.w:wwww ----->7.7.7.7:7777
qe.qe.qe.qe:qeee ----->9.9.9.9:9999


so as you see its just replace main list with other list for specific lines already know and keep the other list not changed .
as i said Y always bigger than X.




the result will be Y same , but just it has replaced the selected ones .

i can have other 3rd file that has the values in Y alone needed to be replaced , so Z has :
f.f.f.f:ffff
u.u.u.u:uuuu
w.w.w.w:wwww
qe.qe.qe.qe:qeee


so as you see i want to lookup in Y , look for Z matched and replace Z with X .


X lines are same as Z lines .
not same values .


i know how to use sed :
find xxx -type f -exec sed -i -e 's/aaaa/bbbb/g' {} \;

but i dont know how to apply it for my scenario above .

if i want to say that my code is correct , i must see the result as below :

0.0.0.0:0000
1.1.1.1:1111
q.q.q.q:qqqq
r.r.r.r:rrrr
2.2.2.2:2222
t.t.t.t:tttt
99.99.99.99:9999
7.7.7.7:7777
9.9.9.9:9999
s.s.s.s:ssss
67.67.67.67:676767




Thanks Folks

Last edited by dr.x; 09-01-2019 at 05:39 PM.
 
Old 09-01-2019, 06:10 PM   #2
BW-userx
LQ Guru
 
Registered: Sep 2013
Location: Somewhere in my head.
Distribution: FreeBSD/Slackware-14.2+/ArcoLinux
Posts: 9,078

Rep: Reputation: 1903Reputation: 1903Reputation: 1903Reputation: 1903Reputation: 1903Reputation: 1903Reputation: 1903Reputation: 1903Reputation: 1903Reputation: 1903Reputation: 1903
all looks like school work. do you know your loops yet, how about nested loops, redirection < > , conditionals, case statements?

what language you using, and what does this have to do with servers?

--
going to ask to redirect this to programming.

not completely tested, you're going to have to finish it, and make sure it is completely working correctly.
Code:
#!/usr/bin/env bash


while read y
do
	while read x
	do
		
		case $y in
		f.f.f.f:ffff)
		echo "1.1.1.1:1111"
		;;
		u.u.u.u:uuuu)
		echo "2.2.2.2:2222"
		;;
		w.w.w.w:wwww)
		echo "7.7.7.7:7777"
		;;
		qe.qe.qe.qe:qeee)
		echo "9.9.9.9:9999"
		;;
		
		esac
	done <x
	
done <y
you x stuff is in the file named x, and the y stuff is in a file called y.

note: the x file is actually totally redundant. because you already know what y match gets replaced with, so that code is actually over kill.

therefore only a read of y file and when it finds the one needed to be replaced with whatever in the x file then just as it is hard coded. no need to use the x file within a the code itself.

you can also put this in a file, make it x then run it on your y file
Code:
sed -i.bak 's|f.f.f.f:ffff|1.1.1.1:1111|' $HOME/testscripts/y
sed -i.bak 's|u.u.u.u:uuuu|2.2.2.2:2222|' $HOME/testscripts/y
sed -i.bak 's|w.w.w.w:wwww|7.7.7.7:7777|' $HOME/testscripts/y
sed -i.bak 's|qe.qe.qe.qe:qeee|9.9.9.9:9999|' $HOME/testscripts/y
that will get the job done too.

Last edited by BW-userx; 09-01-2019 at 06:48 PM.
 
1 members found this post helpful.
Old 09-01-2019, 09:28 PM   #3
dr.x
Member
 
Registered: Jan 2013
Posts: 195

Original Poster
Rep: Reputation: Disabled
Quote:
Originally Posted by BW-userx View Post
all looks like school work. do you know your loops yet, how about nested loops, redirection < > , conditionals, case statements?

what language you using, and what does this have to do with servers?

--
going to ask to redirect this to programming.

not completely tested, you're going to have to finish it, and make sure it is completely working correctly.
Code:
#!/usr/bin/env bash


while read y
do
	while read x
	do
		
		case $y in
		f.f.f.f:ffff)
		echo "1.1.1.1:1111"
		;;
		u.u.u.u:uuuu)
		echo "2.2.2.2:2222"
		;;
		w.w.w.w:wwww)
		echo "7.7.7.7:7777"
		;;
		qe.qe.qe.qe:qeee)
		echo "9.9.9.9:9999"
		;;
		
		esac
	done <x
	
done <y
you x stuff is in the file named x, and the y stuff is in a file called y.

note: the x file is actually totally redundant. because you already know what y match gets replaced with, so that code is actually over kill.

therefore only a read of y file and when it finds the one needed to be replaced with whatever in the x file then just as it is hard coded. no need to use the x file within a the code itself.

you can also put this in a file, make it x then run it on your y file
Code:
sed -i.bak 's|f.f.f.f:ffff|1.1.1.1:1111|' $HOME/testscripts/y
sed -i.bak 's|u.u.u.u:uuuu|2.2.2.2:2222|' $HOME/testscripts/y
sed -i.bak 's|w.w.w.w:wwww|7.7.7.7:7777|' $HOME/testscripts/y
sed -i.bak 's|qe.qe.qe.qe:qeee|9.9.9.9:9999|' $HOME/testscripts/y
that will get the job done too.











Thank you so much for helping , but ..............


#!/usr/bin/env bash


while read y
do
while read x
do

case $y in
f.f.f.f:ffff)
echo "1.1.1.1:1111"
;;
u.u.u.u:uuuu)
echo "2.2.2.2:2222"
;;
w.w.w.w:wwww)
echo "7.7.7.7:7777"
;;
qe.qe.qe.qe:qeee)
echo "9.9.9.9:9999"
;;

esac
done <x

done <y


the :
qe.qe.qe.qe:qeee)
echo "9.9.9.9:9999"


Gonna be from files , so i will dealing with values in a files not a variables as you mentioned in the loop .

the game is how to spin a files values with other files value .


Thanks
 
Old 09-01-2019, 09:44 PM   #4
scasey
Senior Member
 
Registered: Feb 2013
Location: Tucson, AZ, USA
Distribution: CentOS 7.6
Posts: 3,635

Rep: Reputation: 1205Reputation: 1205Reputation: 1205Reputation: 1205Reputation: 1205Reputation: 1205Reputation: 1205Reputation: 1205Reputation: 1205
OP, please use code tags when posting code.

Read z to get $z
Read x to get $x
Read y until the line matches $z; replace the line with $x

Apply that logic using the example BW-userx posted. You’ll need to be sure that the loops through z and x stay in sync if it the position in the file defines the match.

Do you know that the matches in y are in the same sequence as in z?

Edit: Agree this sounds like schoolwork...

Last edited by scasey; 09-01-2019 at 09:46 PM.
 
Old 09-01-2019, 10:32 PM   #5
Firerat
Senior Member
 
Registered: Oct 2008
Distribution: Debian sid
Posts: 1,991

Rep: Reputation: 549Reputation: 549Reputation: 549Reputation: 549Reputation: 549Reputation: 549
I guess the lesson is about bash and sed then

Code:
while read YX;do
     sed -i 's/'${YX%% *}'/'${YX##* }'/' Y
done <feedback

Y
Code:
0.0.0.0:0000
f.f.f.f:ffff
q.q.q.q:qqqq
r.r.r.r:rrrr
u.u.u.u:uuuu
t.t.t.t:tttt
99.99.99.99:9999
w.w.w.w:wwww
qe.qe.qe.qe:qeee
s.s.s.s:ssss
67.67.67.67:676767
feedback
Code:
f.f.f.f:ffff with --> 1.1.1.1:1111
u.u.u.u:uuuu ---> 2.2.2.2:2222
w.w.w.w:wwww -----> 7.7.7.7:7777
qe.qe.qe.qe:qeee -----> 9.9.9.9:9999
I had to fix your feedback a little ( space after some > )
 
Old 09-02-2019, 02:12 AM   #6
dr.x
Member
 
Registered: Jan 2013
Posts: 195

Original Poster
Rep: Reputation: Disabled
Quote:
Originally Posted by Firerat View Post
I guess the lesson is about bash and sed then

Code:
while read YX;do
     sed -i 's/'${YX%% *}'/'${YX##* }'/' Y
done <feedback

Y
Code:
0.0.0.0:0000
f.f.f.f:ffff
q.q.q.q:qqqq
r.r.r.r:rrrr
u.u.u.u:uuuu
t.t.t.t:tttt
99.99.99.99:9999
w.w.w.w:wwww
qe.qe.qe.qe:qeee
s.s.s.s:ssss
67.67.67.67:676767
feedback
Code:
f.f.f.f:ffff with --> 1.1.1.1:1111
u.u.u.u:uuuu ---> 2.2.2.2:2222
w.w.w.w:wwww -----> 7.7.7.7:7777
qe.qe.qe.qe:qeee -----> 9.9.9.9:9999
I had to fix your feedback a little ( space after some > )



thank you very much .

can you tell me which is a file and which is variable ?

X , Y , FEEBACK

i understand FEDDBACK is a file ,
how about X,Y are those files ? or variables ?


Thanks
 
Old 09-02-2019, 04:05 AM   #7
Firerat
Senior Member
 
Registered: Oct 2008
Distribution: Debian sid
Posts: 1,991

Rep: Reputation: 549Reputation: 549Reputation: 549Reputation: 549Reputation: 549Reputation: 549
lol

As Bs Xs Ys
all just labels

YX could have been foo

I think I named it YX because it had the Y values remappped to X

the Y file containing the data which needed fixing
Y should have been B

the important thing is
Do you understand how it works?

can you explain what
${YX%% *} and ${YX##* } are doing?

the sed part is easy
but
can you redo the "while read" to make the sed easier to read ?

hint : you need to clean the feedback data up to make that work.
 
Old 09-02-2019, 07:18 AM   #8
BW-userx
LQ Guru
 
Registered: Sep 2013
Location: Somewhere in my head.
Distribution: FreeBSD/Slackware-14.2+/ArcoLinux
Posts: 9,078

Rep: Reputation: 1903Reputation: 1903Reputation: 1903Reputation: 1903Reputation: 1903Reputation: 1903Reputation: 1903Reputation: 1903Reputation: 1903Reputation: 1903Reputation: 1903
Quote:
Originally Posted by dr.x View Post
Thank you so much for helping , but ..............


#!/usr/bin/env bash


while read y
do
while read x
do

case $y in
f.f.f.f:ffff)
echo "1.1.1.1:1111"
;;
u.u.u.u:uuuu)
echo "2.2.2.2:2222"
;;
w.w.w.w:wwww)
echo "7.7.7.7:7777"
;;
qe.qe.qe.qe:qeee)
echo "9.9.9.9:9999"
;;

esac
done <x

done <y


the :
qe.qe.qe.qe:qeee)
echo "9.9.9.9:9999"


Gonna be from files , so i will dealing with values in a files not a variables as you mentioned in the loop .

the game is how to spin a files values with other files value .


Thanks
Ok this lesson is stupid in my option because it is using one too many files just to preform this simple operation on known values.

you got 3 files. all known values.
Code:
Files are
A:
1.1.1.1:1111
2.2.2.2:2222
7.7.7.7:7777
9.9.9.9:9999

B:
0.0.0.0:0000
f.f.f.f:ffff
q.q.q.q:qqqq
r.r.r.r:rrrr
u.u.u.u:uuuu
t.t.t.t:tttt
99.99.99.99:9999
w.w.w.w:wwww
qe.qe.qe.qe:qeee
s.s.s.s:ssss
67.67.67.67:676767

C:
f.f.f.f:ffff
u.u.u.u:uuuu
w.w.w.w:wwww
qe.qe.qe.qe:qeee

The other is what gets replaced with what part. 

f.f.f.f:ffff with --> 1.1.1.1:1111
u.u.u.u:uuuu ---> 2.2.2.2:2222
w.w.w.w:wwww ----->7.7.7.7:7777
qe.qe.qe.qe:qeee ----->9.9.9.9:9999
all one needs is one file, as i pointed out, feedback on what was done is a simple echo what just took place to be added in.

The only thing I see that can make this a challenge is if file A and C are being used in conjunction
Code:
A:
1)
1.1.1.1:1111
2)
2.2.2.2:2222
3)
7.7.7.7:7777
4)
9.9.9.9:9999

C:
1)
f.f.f.f:ffff
2)
u.u.u.u:uuuu
3)
w.w.w.w:wwww
4)
qe.qe.qe.qe:qeee
therefore using file A and C to tell if it finds line 1 in file B taken from file C then replace it with line 1 in File A within file B.

Then the same for line 2, 3 , and 4. so one can actually change the values within file A and still get the same desired results to the new values from the matching of values in file C in order to reflect this in file B.

Code:
B:
0.0.0.0:0000
f.f.f.f:ffff
q.q.q.q:qqqq
r.r.r.r:rrrr
u.u.u.u:uuuu
t.t.t.t:tttt
99.99.99.99:9999
w.w.w.w:wwww
qe.qe.qe.qe:qeee
s.s.s.s:ssss
67.67.67.67:676767
the feedback is a simple echo out telling a user what just took place to stdout, a file or both.

Using sed with variables. Off the cli.
Code:
$ a=10
$ b=30
$ line="Hey is 10 more than 40?"
$ echo "$line" | sed  's|'$a'|'$b'|' 
Hey is 30 more than 40?

so the basic logic might/should be is to read in C first to get line 1, then read in B next to find match, then read in A to get line 1 to know what to replace line 1 in C with within B, then print out feedback as to what just took place then move onto line 2. repeat until EOF of C or A or is it B?

pretty simple huh?

----------\ OP DO NOT READ ANY FURTHER UNTIL AFTER YOU'VE TRIED GETTING YOUR SOLUTION FIRST \-----------

I am not sure what you will learn from this. you need to know loops and stuff to figure this out. This is yes someone else just did your homework for you. So I strongly suggest you figure out what this is doing, and how it exactly is it doing this. Because this is a very important method of hunt and replace that would be a good to be in your tool box.

Not to mention logic and problem solving being done here.

Code:
#!/usr/bin/env bash
#set -x

while read c
do
	while read b
	do
		if [[ "$c" = "$b" ]] ; then
			#get replace value
			read -r replaceme<A
			#remove that top line
			sed -i.bak '1d' $HOME/testscripts/A
			#do the operation here
			sed -i.bak 's|'$c'|'$replaceme'|' $HOME/testscripts/B
			#give a little feed back
			echo "$c --> $replaceme"
		fi	
	done <B
done <C
 
#note: all files are in same directory along with the script.
#so to explaine the <A and some saying $HOME/testscripts/B where
#just B would work too, but for example between the two depending on where
# the script and files are at. Well, there you have it.
For simplicity, I remove the top line in File A to get it out of the way for the next value needed to be used, therefore putting it right there on the top line again to get.

results
Code:
[userx@FreeBSD64ssd testscripts]$ ./switchstuff
f.f.f.f:ffff --> 1.1.1.1:1111
u.u.u.u:uuuu --> 2.2.2.2:2222
w.w.w.w:wwww --> 7.7.7.7:7777
qe.qe.qe.qe:qeee --> 9.9.9.9:9999
file B before
Code:
0.0.0.0:0000
f.f.f.f:ffff
q.q.q.q:qqqq
r.r.r.r:rrrr
u.u.u.u:uuuu
t.t.t.t:tttt
99.99.99.99:9999
w.w.w.w:wwww
qe.qe.qe.qe:qeee
s.s.s.s:ssss
67.67.67.67:676767
after
Code:
0.0.0.0:0000
1.1.1.1:1111
q.q.q.q:qqqq
r.r.r.r:rrrr
2.2.2.2:2222
t.t.t.t:tttt
99.99.99.99:9999
7.7.7.7:7777
9.9.9.9:9999
s.s.s.s:ssss
67.67.67.67:676767
@Firerat, and others might too come up with a more fandazzly way of doing this as well. Because there is usually more than one way to do things to get the same results in some to most cases.

Last edited by BW-userx; 09-02-2019 at 09:15 AM.
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
how to loop over text file lines within bash script for loop? johnpaulodonnell Linux - Newbie 9 07-28-2015 03:49 PM
[SOLVED] Perl: how to replace blank lines in a file with given lines from another karamaz0v Programming 8 04-19-2012 06:48 AM
replace specific character after specific line by awk Syed Tarique Moin Programming 2 07-19-2010 01:47 PM
replace several lines in a file with other lines in another file if condition yara Linux - General 12 10-27-2009 03:46 PM
Substitute specific lines with lines from another file rahmathullakm Programming 4 01-10-2009 05:47 AM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 06:17 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration