Unix Shell - SED and shell scripting

This is Interesting: Free IT Magazines  
Home > Archive > Unix Shell > February 2005 > SED and shell scripting





You are viewing an archived Text-only version of the thread. To view this thread in it's original format and/or if you want to reply to this thread please [click here]

Author SED and shell scripting
Xancatal

2005-02-25, 5:59 pm

Hey everybody! I need a scripting GURU to decipher this dilemma. I need
to replace a string, and append to the same line. I need to do some
kind of conditional statement before replacing test. For example on thi
file.

abcdefg rt3 #
abcdefg rt4 #
abcdefg rt5 # tke
abcdefg rt6 #
abcdefg rt7 # tke
abcdefg rt8 #

I need to find which of the lines consists of less than 4 fields (line
1), but that is easy. I did it with this nawk script:

nawk '
{if ($NF > 3){
print $0
}
}
` filename

The only problem I have is that once I find this record (rt3), I need
to replace its first field ($1) either within nawk, or use some kind of
sed script once I've obtain the record number (rt3). I have had issues
figuring out how to use the RE on sed for replacing text as in:

sed 's///g' filename

Anyone outthere knows how to use variables on a shell script for making
these changes?

For example:

a="sometext"

and then using the value of ${a} within a sed script for replacing a
string? Thanks GURUs

Chris F.A. Johnson

2005-02-25, 5:59 pm

On Fri, 25 Feb 2005 at 18:03 GMT, Xancatal wrote:
> Hey everybody! I need a scripting GURU to decipher this dilemma. I need
> to replace a string, and append to the same line. I need to do some
> kind of conditional statement before replacing test. For example on thi
> file.
>
> abcdefg rt3 #
> abcdefg rt4 #
> abcdefg rt5 # tke
> abcdefg rt6 #
> abcdefg rt7 # tke
> abcdefg rt8 #
>
> I need to find which of the lines consists of less than 4 fields (line
> 1), but that is easy. I did it with this nawk script:
>
> nawk '
> {if ($NF > 3){
> print $0
> }
> }
> ` filename


Or just:

nawk 'NF > 3' filename

> The only problem I have is that once I find this record (rt3), I need
> to replace its first field ($1) either within nawk,


nawk 'NF > 3 { $1 = newstr; print }' newstr=sometext filename

> or use some kind of sed script once I've obtain the record number
> (rt3). I have had issues figuring out how to use the RE on sed for
> replacing text as in:
>
> sed 's///g' filename
>
> Anyone outthere knows how to use variables on a shell script for making
> these changes?
>
> For example:
>
> a="sometext"
>
> and then using the value of ${a} within a sed script for replacing a
> string? Thanks GURUs


Use double quotes so the variable is expanded:

sed "s/$a/$b/g" filename


--
Chris F.A. Johnson http://cfaj.freeshell.org/shell
========================================
===========================
My code (if any) in this post is copyright 2005, Chris F.A. Johnson
and may be copied under the terms of the GNU General Public License
Xancatal

2005-02-25, 5:59 pm

It might be easiest to replace the string within nawk using sub(), but
then I need to put this replaced string back to the file. In other
words, the change I make has to be reflected on the original file, and
up until now I have only been able to make changes to a string and
display to output on the screen.

Ed Morton

2005-02-25, 5:59 pm



Xancatal wrote:

> Hey everybody! I need a scripting GURU to decipher this dilemma. I need
> to replace a string, and append to the same line. I need to do some
> kind of conditional statement before replacing test. For example on thi
> file.
>
> abcdefg rt3 #
> abcdefg rt4 #
> abcdefg rt5 # tke
> abcdefg rt6 #
> abcdefg rt7 # tke
> abcdefg rt8 #
>
> I need to find which of the lines consists of less than 4 fields (line
> 1),


Lines 1, 2, 4 and 5 all have less than 4 fields.

but that is easy. I did it with this nawk script:
>
> nawk '
> {if ($NF > 3){
> print $0
> }
> }
> ` filename


ITYM:

nawk 'NF<4' filename

> The only problem I have is that once I find this record (rt3), I need
> to replace its first field ($1) either within nawk,


This:

nawk 'NF<4{sub($1,"b");print}' filename

would replace $1 with "b" and print the result.

or use some kind of
> sed script once I've obtain the record number (rt3). I have had issues
> figuring out how to use the RE on sed for replacing text as in:
>
> sed 's///g' filename
>
> Anyone outthere knows how to use variables on a shell script for making
> these changes?
>
> For example:
>
> a="sometext"
>
> and then using the value of ${a} within a sed script for replacing a
> string? Thanks GURUs


sed "s/whatever/$a/" filename

Ed.
..
..
..
..
..
..
..
..
..
Xancatal

2005-02-25, 5:59 pm

Thanks Ed. In this case:

nawk 'NF<4{sub($1,"b");print}' filename

"b" has to be a variable like in:

read var

And once this car can be assigned to nawk via nawk -v myvar=$var, I
would then need to append a space and another entry to the end of the
string, and then write it to a file. Pretty fun ain't it? je je

Xancatal

2005-02-25, 5:59 pm

I forgot to mention the error message:

nawk: illegal field $()
input record number 1, file ethers
source line number 1

This is the result of doing the assignment as such:

nawk -v var=$adr 'NF<4{sub($1,$adr);print}' filename

Ed Morton

2005-02-25, 5:59 pm



Xancatal wrote:

> Thanks Ed. In this case:
>
> nawk 'NF<4{sub($1,"b");print}' filename
>
> "b" has to be a variable like in:
>
> read var
>
> And once this car can be assigned to nawk via nawk -v myvar=$var, I
> would then need to append a space and another entry to the end of the
> string, and then write it to a file. Pretty fun ain't it? je je
>


This would work in gawk (I don't use nawk, but it probably would there too):

awk -v var="$var" 'NF<4{sub($1,var" "otherentry);print > "newfile"}'
filename

or just this:

awk -v var="$var" 'NF<4{sub($1,var" "otherentry);print}' filename > newfile

In the above, otherentry can be a variable or a string.

Regards,

Ed.
Ed Morton

2005-02-25, 5:59 pm



Xancatal wrote:
> It might be easiest to replace the string within nawk using sub(), but
> then I need to put this replaced string back to the file. In other
> words, the change I make has to be reflected on the original file, and
> up until now I have only been able to make changes to a string and
> display to output on the screen.
>


Write the result to a tmp file, then move the tmp file to overwrite the
original. e.g.

nawk '...' file > tmp
mv tmp file

If you can't do that, you can use this approach within your awk program:

function printout(_str) { _out[++_nr] = _str }
function flushout() { close(FILENAME)
for (x=1; x<=_nr;x++)
print _out[x] > FILENAME
}
NF<4{sub($1,"b");printout( $0 ) }
END { flushout() }

i.e. store the modifcations in an array until the end of the program,
then overwrite the original file. I don't use nawk, but the above will
work for gawk and should also work for nawk, perhaps with some small tweaks.

Ed.

Ed Morton

2005-02-25, 5:59 pm



Xancatal wrote:

> I forgot to mention the error message:
>
> nawk: illegal field $()
> input record number 1, file ethers
> source line number 1
>
> This is the result of doing the assignment as such:
>
> nawk -v var=$adr 'NF<4{sub($1,$adr);print}' filename
>


nawk -v var="$adr" 'NF<4{sub($1,var);print}' filename

Ed.
Xancatal

2005-02-25, 5:59 pm

When I use this line:

read myvar

awk -v var="$myvar" 'NF<4{sub($1,$var);print}' filename > newfile

I get the following results:

nawk: illegal field $(sometexttoreplace)
input record number 1, file ethers
source line number 3

I have tried just using double quoted text as in:

awk -v var="$myvar" 'NF<4{sub($1,"sometexttoreplace");print}' filename
> newfile


and it works. The issue here is that I only need to do this replacement
of text on the first instance of NF < 4, and so I would only be sending
that one entry to a newfile. I probably need to somewhat then replace
the entire text for every instance of that record locator. So in this
case:

abcdefg rt3 #
abcdefg rt4 #
abcdefg rt5 # tke
abcdefg rt6 #
abcdefg rt7 # tke
abcdefg rt8 #

I only need to change the first field on "rt3" and bail out. I do so by
using the "exit 0" within awk which basically exits out within the
first instance of NF < 4.

I think I have a problem using the "value" of var (or $var) within the
sub() command.

Xancatal

2005-02-25, 5:59 pm

Thank Ed, This worked pretty cool. I figured after I posted that I was
not supposed to use $ bafore var. I can now edit and bail out. How'bout
concatenating another entry. Perhaps a space. I know that it can be
done as stated on the GNU pages. The only other issue is how to
incorporate this change onto a file which contains the remaining data.

Ed Morton

2005-02-25, 5:59 pm



Xancatal wrote:
> When I use this line:
>
> read myvar
>
> awk -v var="$myvar" 'NF<4{sub($1,$var);print}' filename > newfile
>
> I get the following results:
>
> nawk: illegal field $(sometexttoreplace)
> input record number 1, file ethers
> source line number 3


Yeah you will. STOP ADDING A "$" SIGN TO THE AWK VARIABLE!!!!!

<snip>
> I only need to change the first field on "rt3" and bail out. I do so by
> using the "exit 0" within awk which basically exits out within the
> first instance of NF < 4.


OK. Sounds like you're happy with that, right? Or do you want to
reproduce the other lines as-is?

> I think I have a problem using the "value" of var (or $var) within the
> sub() command.
>


Yes, the problem is that you keep adding a $ sign in front of the awk
variable name!

Ed.
Ed Morton

2005-02-25, 5:59 pm



Xancatal wrote:

> Thank Ed, This worked pretty cool. I figured after I posted that I was
> not supposed to use $ bafore var. I can now edit and bail out. How'bout
> concatenating another entry. Perhaps a space. I know that it can be
> done as stated on the GNU pages. The only other issue is how to
> incorporate this change onto a file which contains the remaining data.
>


See my other responses as I think I've answered all of that already
(depending on what you mean by "entry"). If it still isn't clear, post a
followup.

By the way, please include some context in your postings and try to
avoid starting separate sub-threads for each question, just to lessen
confusion (mine!).

Ed.
Dan Mercer

2005-02-25, 5:59 pm


"Chris F.A. Johnson" <cfajohnson@gmail.com> wrote in message news:389825F51lt52U1@individual.net...
: On Fri, 25 Feb 2005 at 18:03 GMT, Xancatal wrote:
: > Hey everybody! I need a scripting GURU to decipher this dilemma. I need
: > to replace a string, and append to the same line. I need to do some
: > kind of conditional statement before replacing test. For example on thi
: > file.
: >
: > abcdefg rt3 #
: > abcdefg rt4 #
: > abcdefg rt5 # tke
: > abcdefg rt6 #
: > abcdefg rt7 # tke
: > abcdefg rt8 #
: >
: > I need to find which of the lines consists of less than 4 fields (line
: > 1), but that is easy. I did it with this nawk script:
: >
: > nawk '
: > {if ($NF > 3){
: > print $0
: > }
: > }
: > ` filename
:
: Or just:
:
: nawk 'NF > 3' filename
:
: > The only problem I have is that once I find this record (rt3), I need
: > to replace its first field ($1) either within nawk,
:
: nawk 'NF > 3 { $1 = newstr; print }' newstr=sometext filename

This will cause reformatting of $0 compressing field delimiters:

$ awk '{print;$1 = "abc";print}'
123 456
123 456
abc 456

Dan Mercer

:
: > or use some kind of sed script once I've obtain the record number
: > (rt3). I have had issues figuring out how to use the RE on sed for
: > replacing text as in:
: >
: > sed 's///g' filename
: >
: > Anyone outthere knows how to use variables on a shell script for making
: > these changes?
: >
: > For example:
: >
: > a="sometext"
: >
: > and then using the value of ${a} within a sed script for replacing a
: > string? Thanks GURUs
:
: Use double quotes so the variable is expanded:
:
: sed "s/$a/$b/g" filename
:
:
: --
: Chris F.A. Johnson http://cfaj.freeshell.org/shell
: ========================================
===========================
: My code (if any) in this post is copyright 2005, Chris F.A. Johnson
: and may be copied under the terms of the GNU General Public License


Xancatal

2005-02-25, 5:59 pm

Yeah!! I figure that one out Ed!! je je....old scripting habit I guess.
In deed I stop at the first instance of NF < 4. I then redirect the
output to a file which only consists of the newly edited line. I now
need to make it so that that line appears on the source file. I thought
about first finding record (rt3), and then deleting it...appending the
new file to it and re-indexing the file based on its second field.

Thanks for all your help Ed. You're da man!!!

Bye the way... I don't need to reproduce the other lines, just the
first instance of a less than four fields line.



Sponsored Links






Free braindumps | Software forum | Database administration forum

Copyright 2003 - 2008 webservertalk.com