LinuxQuestions.org
Latest LQ Deal: Latest LQ Deals
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 02-25-2011, 11:18 PM   #1
corp769
LQ Guru
 
Registered: Apr 2005
Location: /dev/null
Posts: 5,818

Rep: Reputation: 1007Reputation: 1007Reputation: 1007Reputation: 1007Reputation: 1007Reputation: 1007Reputation: 1007Reputation: 1007
Help with sed script in bash


Code:
#!/bin/bash
VARR=`cat /proc/asound/cards | grep HDMI | cut -c 1-2`
VARX="defaults.ctl.card $VARR"
VARY="defaults.pcm.card $VARR"
FILE1="alsa"
FILE2="alsa.new"
echo $VARX
echo $VARY
sed "s/defaults\.ctl\.card*/'$VARX'/g" $FILE1 > $FILE2
Ok, this is what I have right now. Normally, if I need help with anything, I learn it on my own. Well, I thought I knew sed, and apparently I don't... I tried writing this for someone else, and this has given me trouble, so since the user pretty much figured it out on his own, here it goes.

Say VARR=1, so VARX and VARY contain the above text, appended by 1. What I am trying to do is replace the text "defaults.ctl.card 0" by VARX and "defaults.pcm.card 0" by VARY. The contents of FILE1 is the file being used to search for both text fields, and FILE2 is the output file. I tried using single quotes, double quotes, and a mixture of both, and no go whatsoever. So my question... What is the proper way of searching for text within a file and replacing with a variable?
 
Old 02-26-2011, 12:38 AM   #2
syg00
LQ Veteran
 
Registered: Aug 2003
Location: Australia
Distribution: Lots ...
Posts: 21,119

Rep: Reputation: 4120Reputation: 4120Reputation: 4120Reputation: 4120Reputation: 4120Reputation: 4120Reputation: 4120Reputation: 4120Reputation: 4120Reputation: 4120Reputation: 4120
You don't (shouldn't) need the single quotes at all in that case.
I suspect you need to look more carefully at the regex on the LHS of the substitution.

Last edited by syg00; 02-26-2011 at 12:39 AM.
 
1 members found this post helpful.
Old 02-26-2011, 12:52 AM   #3
David the H.
Bash Guru
 
Registered: Jun 2004
Location: Osaka, Japan
Distribution: Arch + Xfce
Posts: 6,852

Rep: Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037
Without seeing the actual input and output, I can only guess at the real problem. But I think using * alone won't match what you want. You need to use .* instead. Otherwise, as long as you use double-quotes, you shouldn't have any problem with the variable expansion.

How about something like this:
Code:
#!/bin/bash
FILE1="alsa"
FILE2="alsa.new"
VARR=$( grep "HDMI" /proc/asound/cards | cut -c 2 )
sed -r "s/(defaults\.(ctl|pcm)\.card [01])/\1 $VARR/g" $FILE1 > $FILE2
Notes:

$(..) is recommended over `..`

grep can take the filename as an argument, so you don't need cat.

cut -c 1-2 will also give you the blank space in front of the number, and I think you only want the number itself, so I used -c 2 instead.

You can bypass the intermediate variables and just use the original value in your sed expressions.

Finally, with a little regex back-referencing and some grouping, gnu sed will allow you to do the whole thing in a single expression. Or you could also do something like this, which should be more portable:
Code:
sed -e "s/defaults\.ctl\.card [01]/defaults.ctl.card $VARR/g" \
-e "s/defaults\.pcm\.card [01]/defaults.pcm.card $VARR/g"  $FILE1 > $FILE2
 
1 members found this post helpful.
Old 02-26-2011, 06:19 AM   #4
corp769
LQ Guru
 
Registered: Apr 2005
Location: /dev/null
Posts: 5,818

Original Poster
Rep: Reputation: 1007Reputation: 1007Reputation: 1007Reputation: 1007Reputation: 1007Reputation: 1007Reputation: 1007Reputation: 1007
Quote:
Originally Posted by David the H. View Post
Without seeing the actual input and output, I can only guess at the real problem. But I think using * alone won't match what you want. You need to use .* instead. Otherwise, as long as you use double-quotes, you shouldn't have any problem with the variable expansion.

How about something like this:
Code:
#!/bin/bash
FILE1="alsa"
FILE2="alsa.new"
VARR=$( grep "HDMI" /proc/asound/cards | cut -c 2 )
sed -r "s/(defaults\.(ctl|pcm)\.card [01])/\1 $VARR/g" $FILE1 > $FILE2
Notes:

$(..) is recommended over `..`

grep can take the filename as an argument, so you don't need cat.

cut -c 1-2 will also give you the blank space in front of the number, and I think you only want the number itself, so I used -c 2 instead.

You can bypass the intermediate variables and just use the original value in your sed expressions.

Finally, with a little regex back-referencing and some grouping, gnu sed will allow you to do the whole thing in a single expression. Or you could also do something like this, which should be more portable:
Code:
sed -e "s/defaults\.ctl\.card [01]/defaults.ctl.card $VARR/g" \
-e "s/defaults\.pcm\.card [01]/defaults.pcm.card $VARR/g"  $FILE1 > $FILE2
Wow, thanks for the clear description. One thing though.... you mentioned the following - "cut -c 1-2 will also give you the blank space in front of the number, and I think you only want the number itself, so I used -c 2 instead." On my machine, even though your example worked flawlessly, my cut command worked too. But I'm not complaining, and thank you for the example. I learned a lot from that.

Thanks again man!

Josh
 
Old 02-26-2011, 03:25 PM   #5
David the H.
Bash Guru
 
Registered: Jun 2004
Location: Osaka, Japan
Distribution: Arch + Xfce
Posts: 6,852

Rep: Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037
Well, I was basing it on the output I got from my own /proc/asound/cards, which shows a space at the beginning of each card line. I suppose it's possible you get something different. More likely it's actually there in yours too, but isn't affecting anything, as the size of the blank space doesn't usually matter in most configuration-type files.

But since you only want to extract a single digit, it's hard to see how having it cut two characters would be desirable no matter what the actual effect.
 
Old 02-26-2011, 03:27 PM   #6
corp769
LQ Guru
 
Registered: Apr 2005
Location: /dev/null
Posts: 5,818

Original Poster
Rep: Reputation: 1007Reputation: 1007Reputation: 1007Reputation: 1007Reputation: 1007Reputation: 1007Reputation: 1007Reputation: 1007
I know what I did - I copied the cut command out of one of my other scripts and pasted it in (Yes, I was that lazy - I was drinking....) and when I did paste it in, it worked. I guess bash took the space out. Or maybe gremlins inside my computer saw the space and killed it? Oh well, works as advertised
 
  


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
error when using sed in a bash script raprat Programming 3 11-09-2009 11:21 PM
bash script using sed or awk? houms Linux - Newbie 10 06-21-2009 09:14 AM
Help with BASH script and AWK and SED NickJH Linux - Newbie 11 03-07-2009 04:08 PM
problem with sed in a bash script nexus55 Linux - Software 6 05-03-2004 09:40 PM
sed in small BASH script OhLordy Linux - General 1 08-29-2003 11:32 AM

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

All times are GMT -5. The time now is 08:28 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