Anyone got any AWK coding experience?
Anyone got any AWK coding experience?
Author
Discussion

neil_cardiff

Original Poster:

17,113 posts

294 months

Tuesday 10th January 2006
quotequote all
Got a bit of a stumper of a problem

zumbruk

7,848 posts

290 months

Tuesday 10th January 2006
quotequote all
neil_cardiff said:
Got a bit of a stumper of a problem


"Bailing out near Line 1"

Rewrite the sucker in perl. Believe me, it'll be quicker and easier in the long run.

neil_cardiff

Original Poster:

17,113 posts

294 months

Tuesday 10th January 2006
quotequote all
zumbruk said:
neil_cardiff said:
Got a bit of a stumper of a problem


"Bailing out near Line 1"

Rewrite the sucker in perl. Believe me, it'll be quicker and easier in the long run.


LOL

I've come across this and its a cracker

Anyway, seriously, anyone?

annodomini2

6,971 posts

281 months

Tuesday 10th January 2006
quotequote all
a bit but its been a while.

TheExcession

11,669 posts

280 months

Tuesday 10th January 2006
quotequote all
annodomini2 said:
a bit but its been a while.

Likewise...

What are you trying to do?

neil_cardiff

Original Poster:

17,113 posts

294 months

Tuesday 10th January 2006
quotequote all
TheExcession said:
annodomini2 said:
a bit but its been a while.

Likewise...

What are you trying to do?


Not at work any more but look in tommorrow and I'll explain more. It's quite a simple one really to do with stripping a DOS file of it's separators and converting it to unx format.

More tommorrow - I've had enough of the bloody thing...

neil_cardiff

Original Poster:

17,113 posts

294 months

Wednesday 11th January 2006
quotequote all
Right!

Scenario: An EDI transmission creates a DOS text file, which needs to be read by out BO system, which is a UNIX based. Hence we need to first remove the Line Returns, and then convert the file to unix format ready to be imported into our system (in a csv format but as a text file).

The file is importh.txt and should eventually come out as that.

The AWK code is here (hoping the formatting works):

cd /u/3ex/fw/in
dtox horders.txt > horders.unx
mv horders.unx horders.txt

FILE=horders.txt
awk '
BEGIN{FS=","}
{
if ($1=="HEAD"
{
REF=substr($5,length($5)-9);
print $0 "," REF ",";
}
if ($1=="LINE"
{
print $0 "," REF ",";
}
if ($1=="TEXT"
{
print $0 "," REF ",";
}
}' < $FILE > orders.txt

Can anyone explain why the script isn't working? if I remove the 'cd' bit to just locally run everything, it falls over at the 'dtox' part (removing the separators)...?

Cheers

Neil

Edited to Add: Nope, it removed all the tabs - but the emphasis is the same

>> Edited by neil_cardiff on Wednesday 11th January 09:31

TheExcession

11,669 posts

280 months

Wednesday 11th January 2006
quotequote all
Hi Neil,
Any chance you could post the first few lines of the input file and then provide an example of what you want it to end up as?

cheers

neil_cardiff

Original Poster:

17,113 posts

294 months

Wednesday 11th January 2006
quotequote all
TheExcession said:
Hi Neil,
Any chance you could post the first few lines of the input file and then provide an example of what you want it to end up as?

cheers


Original:

HEAD, KAUFMANN, FOCUS, FOCUS-1229, 001229267167, 06/01/2006, , , , , , , , , , , , , , , , , , , , , , , , , ,
LINE, 1, KL114W, , 1, 5010763042013, 018377, , , 0.0000, TWISTED ROPE WASTE BIN, 2.27, , , , ,
LINE, 2, KB358, , 2, 5010763056614, 018391, , , 0.0000, SGRS & CHRM WASTE BIN, 3.36, , , , ,
LINE, 3, KB234, , 1, 5010763054207, 020162, , , 0.0000, CHOC RAT&CHR DSKTP FIL STG, 6.1, , , , ,
LINE, 4, KB93L, , 2, 5010763025870, 981260, , , 0.0000, LRGE SEA GRSS STORAGE BSKT, 5.82, , , , ,
LINE, 5, KB115, , 1, 5010763041061, 987600, , , 0.0000, SEA GRASS SHELF BASKET, 3.3, , , , ,
LINE, 6, KB135, , 2, 5010763043126, 987624, , , 0.0000, S'GRSS/CHRM EF SML FILE BX, 14.24, , , , ,
RECON, KAUFMANN, FOCUS, 001229267167, 6

Should end up like this:

HEAD, HORWOODS, ALLD, ALL-CENTWH, 008-71404165, 26/12/2004, 02/01/2005, 00:00:00, , , , , , , , , , , , , , , , , , , , , , , , ,8-71404165,
LINE, 1, S102, , 48, 5010763001980, 0038601-1, , , 0.0000, 14CM MILK SAUCE POT, 7.55000019, , , , , ,8-71404165,
LINE, 2, S104, , 12, 5010763001997, 0038442-0, , , 0.0000, 14CM SAUCEPAN, 9.5, , , , , ,8-71404165,
LINE, 3, S105, , 15, 5010763002000, 0038448-7, , , 0.0000, 16CM SAUCEPAN, 10.7200002, , , , , ,8-71404165,
LINE, 4, S106, , 8, 5010763002017, 0038454-5, , , 0.0000, 18CM SAUCEPAN, 11.6999998, , , , , ,8-71404165,
LINE, 5, S107, , 22, 5010763002024, 0038459-4, , , 0.0000, 20CM SAUCEPAN, 12.9099998, , , , , ,8-71404165,
LINE, 6, S119, , 3, 5010763002086, 0038482-6, , , 0.0000, 24CM FRYPAN OPEN, 15.2200002, , , , , ,8-71404165,

END

neil_cardiff

Original Poster:

17,113 posts

294 months

Wednesday 11th January 2006
quotequote all
Oh. Just realised it dosen't come out very well in this forum

Neil

TheExcession

11,669 posts

280 months

Wednesday 11th January 2006
quotequote all
Hi Neil,

Sorry mate got called away...

Soeesentially you are reading a REF var fr omthe HEAD line and then appending it to every other 'TEXT' or 'LINE' line in the file.

The awk looks fine to me, to remove the cd part you need to provide the full path for the dtox to work.

dtox /u/3ex/fw/in/horders.txt > /u/3ex/fw/in/horders.unx

I'd then make sure you fully path in rteferences to the other files.

rebelstar

1,146 posts

274 months

Wednesday 11th January 2006
quotequote all
You could use "tr" instead of awk...

tr -d '\r' < importh.txt > importh.tmp
mv importh.tmp importh.txt

PH changed my backslash r to a new line for me

>> Edited by rebelstar on Wednesday 11th January 13:08

neil_cardiff

Original Poster:

17,113 posts

294 months

Wednesday 11th January 2006
quotequote all
TheExcession said:
Hi Neil,
Soeesentially you are reading a REF var fr omthe HEAD line and then appending it to every other 'TEXT' or 'LINE' line in the file.


What does this line do? We can't figure out what it is trying to achieve...!

We are getting very very fustrated!

zumbruk

7,848 posts

290 months

Wednesday 11th January 2006
quotequote all
neil_cardiff said:
Right!

Scenario: An EDI transmission creates a DOS text file, which needs to be read by out BO system, which is a UNIX based. Hence we need to first remove the Line Returns, and then convert the file to unix format ready to be imported into our system (in a csv format but as a text file).

The file is importh.txt and should eventually come out as that.

The AWK code is here (hoping the formatting works):

cd /u/3ex/fw/in
dtox horders.txt > horders.unx
mv horders.unx horders.txt


Don't like this. Depending on file permissions and the value of the shell "noclobber" variable, you may or may not end up with what you thought in your 'horders.txt' file. I would change this to read;

cd /u/3ex/fw/in
dtox horders.txt > horders.unx

Then read the "unx" file directly in the "awk" script;

FILE=horders.unx

neil_cardiff said:

awk '
BEGIN{FS=","}


This sets the field seperator to ",". Each line read form now on is split
into fields, remembering that the first field is number 1, on the commas. Field
'0' is the whole input line.

neil_cardiff said:

{
if ($1=="HEAD"
{
REF=substr($5,length($5)-9);
print $0 "," REF ",";
}

So, if the *first* field is the string "HEAD", set the variable "REF" to
be the last 9 characters of the fifth field, then print the whole line
with ",xxxxx," on the end.
neil_cardiff said:


if ($1=="LINE"
{
print $0 "," REF ",";
}
if ($1=="TEXT"
{
print $0 "," REF ",";
}

If the first field is "LINE" or "TEXT", just repeat the print, without setting
the REF variable.

neil_cardiff said:


}' < $FILE > orders.txt

Can anyone explain why the script isn't working? if I remove the 'cd' bit to just locally run everything, it falls over at the 'dtox' part (removing the separators)...?


"Falls over"? What's the error message?

If you email me your 'phone number, I'm happy to call and try and talk you through this... (Although my suggestion of rewriting it in perl was serious!)

Regards,

Z.


>> Edited by zumbruk on Wednesday 11th January 13:36

TheExcession

11,669 posts

280 months

Wednesday 11th January 2006
quotequote all
neil_cardiff said:

FILE=horders.txt
awk '
BEGIN{FS=","}
{
if ($1=="HEAD"
{
REF=substr($5,length($5)-9);
print $0 "," REF ",";
}
if ($1=="LINE"
{
print $0 "," REF ",";
}
if ($1=="TEXT"
{
print $0 "," REF ",";
}
}' < $FILE > orders.txt


What does this line do? We can't figure out what it is trying to achieve...!


Hey Neil, awk just takes a file and reads it one line at a time, and if you tell it to will act upon the contents of that line.

An awk comand has 3 parts/sections, an BEGIN, MAIN and END, the code in the 'begin' section is execute once when the cammonad is called, normally it's where you initailse variables etc.

Code in the 'MAIN' section is exected for every line in the input file.

Code at the 'END' is executed once after the input file has been processed.

so in your BEGIN section you declare FS=',' FS is the field separator, so when processing lines in the MAIN section awk will separate each line into an array of fields based upon seeing a comma in the input line.

Once you get into main...
Fields from the input line are tested by referencing them using $, $0 is the entire input line, $1 is the first data field, $2 the second etc etc, all determined by pressence of the FS - in your case a ','.

so the lines

if ($1=="HEAD"
{
REF=substr($5,length($5)-9) ;
print $0 "," REF "," ;
}

say's if the first field contain 'HEAD' (in your case this is how the code is identifying the first line of the file) then delcare a variable called REF

assign this var the value of field 5 - but using a substring function, in your data

HEAD, KAUFMANN, FOCUS, FOCUS-1229, 001229267167, 06/01/2006, , , , , , , , , , , , , , , , , , , , , , , , , ,
field 5 is 001229267167, but then it takes a substring of this such that it uses the last 9 characters - 1229267167, so fro mnow on REF=1229267167

the line print $0 "," REF "," ;
prints the enitre line but also adds ',1229267167,' to the end of it.

The next few test lines say

if ($1=="LINE" ) .... or if ($1=="TEXT" ) these are looking at the 1st field of the Input line, if the Value is TEXT or LINE then the line is printed, again with the added REF variable on the end.

so awk is taking the input file, when it sees the HEAD field it outputs the entire line with the extra extracted REF info on the end. For every other line in the file, providing the line begins with LINE or TEXT it will out put that line with the extra REF info.

all output form awk is being redirected intoyour output file...

< $FILE > orders.txt

it uses what ever is in $FILE for input and all output goes to orders.txt

HTH



edit: Doh beaten to it by zumbruk - almost word for word there



>> Edited by TheExcession on Wednesday 11th January 13:39

GreenV8S

31,024 posts

314 months

Wednesday 11th January 2006
quotequote all
To start with, put the awk script in a separate file rather than in-line on the awk command line; this way you will get sensible error messages.

zumbruk

7,848 posts

290 months

Wednesday 11th January 2006
quotequote all
neil_cardiff said:
Right!
}' < $FILE > orders.txt


That line just means "read input from the file whose name is in the variable $FILE and write it to a file called orders.txt". It's not part of AWK, that's standard Unix shell syntax.

You set the $FILE variable in the START part of the program; AWK programs have 3 parts, a START part which is executed once before any data is read, a main section which is executed once for every line in the input file and a FINISH part which is executed once after all the data is read.


>> Edited by zumbruk on Wednesday 11th January 13:50

neil_cardiff

Original Poster:

17,113 posts

294 months

Wednesday 11th January 2006
quotequote all
Cheers Guys,

I'll print this out and take a long look at what you've written, I really appreciate you help (owe you beers).

I'll have a play and report back/

Neil

zumbruk

7,848 posts

290 months

Wednesday 11th January 2006
quotequote all
GreenV8S said:
To start with, put the awk script in a separate file rather than in-line on the awk command line; this way you will get sensible error messages.


You reckon?

What you'll actually get is awk's famous and utterly useless universal error message "Bailing out near line 1". (Besides, I don't think this is an awk problem - I think he's reading the wrong file cos the d2x is going wrong.)

Anyhow, Neil, if you do that, you need to change your script to something like,

awk -f awkfile < inputfile > outputfile

(It's very hard trying to do this on Pistonheads, 'cos when you're composing an answer you can't see the original unless you quote it and then you're into the [quote][/unquote] nonsense.

GreenV8S

31,024 posts

314 months

Wednesday 11th January 2006
quotequote all
zumbruk said:
GreenV8S said:
To start with, put the awk script in a separate file rather than in-line on the awk command line; this way you will get sensible error messages.


You reckon?


Well, sensible in the sense that it will give a line number and you can then go to that line number and see where the problem occurs, rather than the 'somewhere near line 1' mallarky.