LinuxQuestions.org
Welcome to the most active Linux Forum on the web.
Go Back   LinuxQuestions.org > Forums > Linux Forums > Linux - Newbie
User Name
Password
Linux - Newbie This Linux forum is for members that are new to Linux.
Just starting out and have a question? If it is not in the man pages or the how-to's this is the place!

Notices


Reply
  Search this Thread
Old 07-18-2016, 08:47 AM   #1
pradeepspa
Member
 
Registered: Oct 2015
Posts: 79

Rep: Reputation: Disabled
Call each line in a file as an argument to another command in Bash


Hi All,

I am new to bash script so please done mind if my question is trivial.

I am trying to build a script where I need to call each line of a file , use it as input to sed and generate output. This should follow for rest of the lines as well.

I was using the below one but doesnt seems to be working. Could someone give me a hand in debugging this or provide anyother solution ?


old="hi"
new="bye"
while I= read -r a; do
sed -i -e "/^$a/s/$old/$new/" /tmp/test.txt
done </tmp/tacfile.txt
 
Old 07-18-2016, 09:04 AM   #2
keefaz
LQ Guru
 
Registered: Mar 2004
Distribution: Slackware
Posts: 6,552

Rep: Reputation: 872Reputation: 872Reputation: 872Reputation: 872Reputation: 872Reputation: 872Reputation: 872
Not sure what the I= is for, but you'll need a space after /^$a/, before s/$old/$new/

[edit]
No it seems to work as this (without the space)
It won't generate output with the -i option (edit file in place)

Last edited by keefaz; 07-18-2016 at 09:08 AM.
 
1 members found this post helpful.
Old 07-18-2016, 09:33 AM   #3
HMW
Member
 
Registered: Aug 2013
Location: Sweden
Distribution: Debian, Arch, Red Hat, CentOS
Posts: 773
Blog Entries: 3

Rep: Reputation: 369Reputation: 369Reputation: 369Reputation: 369
Hi!

Please use code tags when posting code, it makes for much easier reading.

It seems to me that you are complicating things. Given this infile:
Code:
hi foo
bye bar
hi foobar
I would use this little thing:
Code:
#!/bin/bash

old="hi"
new="bye"

while read -r line; do
    echo $line | sed "s/$old/$new/"
done < in.txt

exit 0
Or even a straight sed from the command line, like this:
Code:
sed 's/hi/bye/g' in.txt 
bye foo
bye bar
bye foobar
Best regards,
HMW
 
1 members found this post helpful.
Old 07-18-2016, 10:33 AM   #4
grail
LQ Guru
 
Registered: Sep 2009
Location: Perth
Distribution: Manjaro
Posts: 10,005

Rep: Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191
Quote:
I was using the below one but doesnt seems to be working.
Please don't use simple terms ike this as there is nothing to be gleaned from this information. Instead explain 'what is not working' or 'why YOU think it doesn't work'.

And as shown by HMW, provide some input, actual output and expected output, plus any error messages if any.

Also, in future, please use [code][/code] tags around code / data so it is more legible and maintains formatting.
 
Old 07-18-2016, 11:39 AM   #5
pan64
LQ Addict
 
Registered: Mar 2012
Location: Hungary
Distribution: debian/ubuntu/suse ...
Posts: 21,784

Rep: Reputation: 7304Reputation: 7304Reputation: 7304Reputation: 7304Reputation: 7304Reputation: 7304Reputation: 7304Reputation: 7304Reputation: 7304Reputation: 7304Reputation: 7304
Quote:
Originally Posted by HMW View Post
Code:
while read -r line; do
    echo $line | sed "s/$old/$new/"
done < in.txt

exit 0
HMW
I'm really sorry, but I do not like that kind of "solutions"
I mean you created an unnecessary loop, therefore you have now loop (of sed) inside loop (of while).
That is very, very ineffective, this is something called "bad practice".
A much better solution would be (yes, I know you know it, so just to repeat):
Code:
sed "s/$old/$new/" in.txt
 
Old 07-18-2016, 12:27 PM   #6
HMW
Member
 
Registered: Aug 2013
Location: Sweden
Distribution: Debian, Arch, Red Hat, CentOS
Posts: 773
Blog Entries: 3

Rep: Reputation: 369Reputation: 369Reputation: 369Reputation: 369
Quote:
Originally Posted by pan64 View Post
I'm really sorry, but I do not like that kind of "solutions"
No need to be sorry, I agree completely. I just modified OP's original attempt so it at least works!
Quote:
Originally Posted by pan64 View Post
A much better solution would be (yes, I know you know it, so just to repeat):
Code:
sed "s/$old/$new/" in.txt
Yep!
 
Old 07-18-2016, 01:56 PM   #7
keefaz
LQ Guru
 
Registered: Mar 2004
Distribution: Slackware
Posts: 6,552

Rep: Reputation: 872Reputation: 872Reputation: 872Reputation: 872Reputation: 872Reputation: 872Reputation: 872
Not sure I follow well but
Code:
sed "s/$old/$new/" in.txt
Is not exactly what OP required with
Code:
sed "/^$a/s/$old/$new/" in.txt
Replace $old with $new if /^something else/
 
Old 07-18-2016, 02:13 PM   #8
pradeepspa
Member
 
Registered: Oct 2015
Posts: 79

Original Poster
Rep: Reputation: Disabled
Guys Thanks a lot for the response. I should have been more clear in my point. Sorry about that.

The reason why I use sed is not to change the sting directly.

Example.
In file test.txt,

hi My name is Pradeep
bye My name is Pradeep

sed -i -e "/^hi/s/Pradeep/spa/"

So wherever i find "hi" as first occurance of a line, I need to change "Pradeep" to "Spa". Here "Hi" is not static where I have list of variables which i need to call from a file /tmp/tacfile.txt.
 
Old 07-18-2016, 04:44 PM   #9
keefaz
LQ Guru
 
Registered: Mar 2004
Distribution: Slackware
Posts: 6,552

Rep: Reputation: 872Reputation: 872Reputation: 872Reputation: 872Reputation: 872Reputation: 872Reputation: 872
So your script works
 
Old 07-18-2016, 04:50 PM   #10
pradeepspa
Member
 
Registered: Oct 2015
Posts: 79

Original Poster
Rep: Reputation: Disabled
Not exactly. For some reason its changing all instance regardless of my condition (hi or bye)
 
Old 07-18-2016, 05:14 PM   #11
pradeepspa
Member
 
Registered: Oct 2015
Posts: 79

Original Poster
Rep: Reputation: Disabled
could someone know why its not filtering properly. Usage of sed is not proper or anything? I ran manually where it works. Only as a whole file its not
 
Old 07-18-2016, 05:25 PM   #12
keefaz
LQ Guru
 
Registered: Mar 2004
Distribution: Slackware
Posts: 6,552

Rep: Reputation: 872Reputation: 872Reputation: 872Reputation: 872Reputation: 872Reputation: 872Reputation: 872
Maybe remove -i option and redirect output to a temp file then move temp file to test.txt

edit:
wrong approach, I was thinking of capturing output from loop but the test.txt content will repeat after each loop iteration.

I would be curious to see test.txt and tacfile.txt content though

Another idea would be to build match pattern from tacfile.txt
something like: ^something|^thing|^this|^that

Code:
old="hi"
new="bye"

a=$(sed 's/.*/^&/' /tmp/tacfile.txt | paste -s -d'|' -)

sed -r -i -e "/$a/s/$old/$new/" /tmp/test.txt

Last edited by keefaz; 07-18-2016 at 05:59 PM.
 
Old 07-18-2016, 05:54 PM   #13
pradeepspa
Member
 
Registered: Oct 2015
Posts: 79

Original Poster
Rep: Reputation: Disabled
changed the condition to " sed -i -e "/$a/ s/$old/$new/ ; /$a/! s/$old/$old/" which did the work.

Thanks all for helping
 
Old 07-18-2016, 11:08 PM   #14
grail
LQ Guru
 
Registered: Sep 2009
Location: Perth
Distribution: Manjaro
Posts: 10,005

Rep: Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191
Well that makes little sense as to why you would need to go that way. Are you sure the file(s) being edited aren't originally Windows files? The dodgy line endings could be messing up sed.
 
Old 07-19-2016, 11:31 AM   #15
pradeepspa
Member
 
Registered: Oct 2015
Posts: 79

Original Poster
Rep: Reputation: Disabled
They are not windows file. Just a text file on linux.
 
  


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
(SOLVED) bash shell read user argument from command line and test it atnonis Programming 12 08-30-2010 07:11 AM
bash script 'for each command line argument' true_atlantis Linux - Newbie 3 01-28-2009 01:51 PM
[SOLVED] pass file-name as command line argument vikas027 Programming 2 10-14-2008 11:52 PM
Finding the last command line argument (bash) pete1234 Programming 20 10-30-2006 10:20 AM
Redirecting output to a command-line argument of another command madiyaan Linux - Newbie 1 02-19-2005 04:35 PM

LinuxQuestions.org > Forums > Linux Forums > Linux - Newbie

All times are GMT -5. The time now is 12:07 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
Open Source Consulting | Domain Registration