LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (https://www.linuxquestions.org/questions/programming-9/)
-   -   help with sed. newbie. (https://www.linuxquestions.org/questions/programming-9/help-with-sed-newbie-389905/)

ronsha 12-06-2005 02:05 PM

help with sed. newbie.
 
Hello.

I have a file of this type:
<name=item1 permission=1001 value=info id=345>
<name=item2 permission=1001 id=356 value=warn>
<name=item1 value=debug permission=1001 id=355>
<name=item2 permission=1010 value=info id=789>
<name=item1 permission=1100 value=blank id=222>

What I need is to write a script that will read this file and replace the value string only on item1 tags with a different string.
So in this example 3 lines ought to be changed. As you can see the value is not in a fixed location and can have different values as well.
I'm sure I can do this with sed but I'm new to this and need help.

I wrote a small script that will read the file and will output the item1 lines and will export it to a file. Obviusly I need to change my sed to search and replace rather than just print and this is where you smart people come.

Here is my script:
#!/bin/sh

if [ $# -eq 1 ]; then
full_path="$1"
else
full_path="/tmp/yar/file"
fi
if [ -f $full_path ]; then
sed -n '/item1/p' < $1 > output.log
else
echo "Invalid path $1"
exit 1
fi

keefaz 12-06-2005 02:27 PM

Use the sed syntax s// (and maybe read man sed :))
Code:

sed -e 's/item1/whatever/g' $full_path > output.log

ronsha 12-06-2005 02:32 PM

Thanks Keefaz.

I have read man sed and tried a few things.
Wouldn't your solution replace the string item1 with whatever? Sorry for not being very clear. What I need is to replace the value string on item1 lines. something like this:
before sed- <name=item1 permission=1001 value=info id=345>
after sed - <name=item1 permission=1001 value=whatever id=345>

The value will change only on item1 lines but the rest is the same including the item1 string.

keefaz 12-06-2005 02:39 PM

This one will do :
Code:

sed -e 's/\(.*item1.*value=\)\(.*\) \( .*\)/\1whatever \3/' $full_path > output.log
I am not a sed expert though, maybe it can be shortcutted

ronsha 12-06-2005 02:50 PM

thanks again.
tried it but it didn't work (copied the entire file to the output file without a change)

You may have something there though. I'll try to understand your regular expression and hopefully find out what's wrong.

keefaz 12-06-2005 02:56 PM

Maybe this one ?
Code:

sed -e 's/\(.*item1.*value=\)\([^ ]\+\) \(.*\)/\1whatever \3/' $full_path > output.log
.* : matches any character
[^ ]\+ : matches a word

ronsha 12-06-2005 03:05 PM

yep ! that one did the trick.

Now all i have to do is to understand everything you did there... :)

Thanks a lot.

keefaz 12-06-2005 03:12 PM

Note that it works only if name=item1 is placed before value=
It won't work with a line like :
<permission=1001 value=info id=345 name=item1>

Here I can't think how deal with sed, but in perl, I could do :
Code:

perl -p -e 's/value=([^ ]+)/value=whatever/ if /item1/;' $full_path > output.log
This way, item1 can be located anywhere in the line

ronsha 12-06-2005 03:26 PM

I see. in my case the item will always be the first thing.

I really need to learn the basics of regular expressions as it looks like ancient chineese to me now..lol...

Appriciate your help.

WindowBreaker 12-14-2005 10:07 PM

A simple sed solution
 
sed '/item1/s/value=[^ ]*/value=whatever/g' <inputfile>

The '/item1/' means to only do the following command on lines that contain the string "item1" (it's an address in sed terms).

's' is a search & replace command.
/value=[^ ]*/ will match 'value=' followed by non-whitespace characters.
/value=whatever/g will globally (all occurrences, not just the first) replace it with value=whatever.

The g (global) flag isn't necessary if there's only one value=something per line.

Sed's man page sucks. So does it's info page. It took me a while to find a good thorough tutorial, but here's the link if you're interested:
http://www.grymoire.com/Unix/Sed.html

I hope that helps.

Pablo


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