1829857 Members
2109 Online
109993 Solutions
New Discussion

newbie

 
Allen Stacey
New Member

newbie

I need some help on a shell script that will take one file which looks like this:

F=13141

and rewrite it to look like this

14155=12141

The same Letters will always have the same number tied to it.

It also needs to do this on every file in the directory
5 REPLIES 5
RAC_1
Honored Contributor

Re: newbie

Eloberate more. what exactly you want?

you can do ll|grep "F="

mv $1 another_file_name
There is no substitute to HARDWORK
Allen Stacey
New Member

Re: newbie

I need a simple script that will take one file that looks like this:

F=121414

and compare it to a cross reference table
F=12

then rewrite the file like this

12=121414
Scott Van Kalken
Esteemed Contributor

Re: newbie

best to use sed or awk to do this.

You can even be cheeky and do it using vi. I do it for billing info we send to our vendors to put a state code ($ENVIRONMENT) into each file, then concatenate all individual files into one big one.

#!/bin/sh

update_file()
{
vi - $ENVIRONMENT <:1,%s/^/$ENVIRONMENT,/g
:wq!
EOF
}

for i in `ls -la [A-Z]* | awk '{print $9}'`
do
ENVIRONMENT=$i
update_file $ENVIRONMENT
done

for i in `ls -la [A-Z]* | awk '{print $9}'`
do
cat $i >> BILLS
done



the bit that does it with vi is the "update_files" bit.

So if you're familar with vi you can do it like:

vi - FILE << EOF
:1,%s/^F/12345/g
:1,%s/^G/67890/g
:wq!
EOF

That will do the one file. It

: = vi command mode
:1 = go to first line
, = next command
%s = search
%s/^F/ = search from beginning of line for F (^ is anchor)

%s/^F/123456/g = search from beginning of line for F and replace with 123456 for the entire file.

This is using vi.....

if you want to use sed, you'd do it like this:

#!/bin/sh
do_sub(){
while read a; do
sed 's/,b/,n/g' $a > $a.new
done
}


########################################
# Main script - messy but does the job #
########################################
ll *.ent | awk '{print $9}' > list.txt

do_sub < list.txt


This oen replaces ",b" with ",n" in all .ent files in a given directory.

I could make it better, but I only ever needed to run it once.

Once again, the sed statement is:

s = search
/,b/ first thing to search for
/,n/ replace it with
g = entire file.

Neither one is truly brillian and I'm sure you'll get a lot better answers from other people here, but I never have a need to run this stuff on a regular basis.

Hope it helps anyhow.

Scott.
Scott Corzine
Advisor

Re: newbie

Hi Allen-

It's the cross-referencing that makes it tricky. I understand your situation to be:

You have a directory ("foodir/") which contains several files ("bar1", "bar2", bar3", etc"). You have one cross-reference file ("xref"). You want to rewrite each bar file individually base on xref. The contents of xref look like:

F=12
G=13
...

The bar files look like:

F=12141
G=14234
...

The desired result is:

12=12141
13=14234
...

There are no duplicate letters in xref, and it doesn't matter whether the bar files have dups.


Basically, you want to have the shell script do a loop through each file in the directory, and on each loop to process the files. Because you're cross-referencing, it's easiest to process each file with the associative arrays (hashes) in perl or awk (more complex solutions use sed or the like instead).

I'm attaching a heavily commented perl script which will handle the above. It could be made shorter and less comprehensible (crunched down to one line illegible line in the extreme).


The solution using sed is shorter, but much, much less efficient because it has to go through each file and rewrite it once for each line in the xref file. If you need, I can post it.

-Scott-
Scott Corzine
Advisor

Re: newbie

Ok, duh, I forgot a trick that makes sed pretty easy and efficient too.

First use sed to process the xref file into a fresh sed script:

sed -e 's@^\([A-Za-z]*\)=\([0-9]*\)$@s/^\1=/\2=/@' xref > xref.sed

Then use that new sed script on each file:

for file in bar*
do sed -f xref.sed $file > Done.$file
done

Explainations about the regular expression can be found in the perl script I posted earlier, note that perl and sed are a little different in their regular expressions (e.g. sed wants "\(" where as perl wants "(").

You'll note that this is similar to Scott Van Kalken's vi commands, which is understandable because both sed and the vi line mode (: commands) are based on the same older editor ed.

It's easy to get used to using a tool in a particular way, then forgetting what else it can do. In this case I always use sed on the command line with "-e" and forgot that it can take a sed script as a file with "-f".


Oh well, hope this helps,
-Scott-