OR operator syntax question in AWK script

Hi guys,

I confused about syntax used in OR script as follow:

I have this sample file separated by "|" containing:

January|Month No. 1
February|Month No. 2
March|Month No. 3
April|Month No. 4
May|Month No. 5
June|Month No. 6
July|Month No. 7
August|Month No. 8
September|Month No. 9
October|Month No. 10
November|Month No. 11
December|Month No. 12

And I�m excluding 6 lines containing the first 6 months with this awk script (and works fine):

awk 'BEGIN {OFS=FS="|"; IGNORECASE=1} $1 !~ /january|february|march|april|may|june/' file

July|Month No. 7
August|Month No. 8
September|Month No. 9
October|Month No. 10
November|Month No. 11
December|Month No. 12

The problem is when I try to write the same one-line command in 2 or more lines, because I get errors, I mean:

awk 'BEGIN {OFS=FS="|"; IGNORECASE=1} $1 !~ /january|february|
march|april|may|june/' file

awk: BEGIN {OFS=FS="|"; IGNORECASE=1} $1 !~ /january
awk:                                         ^ unterminated regexp
awk: cmd. line:1: |february|march|april|may|june/
awk: cmd. line:1: ^ syntax error

What I�m doing wrong? how can I fix it?

  • I try to do this because in the real file I need to exclude more than 20 patterns from a column and the one-line command becomes too long.

Any help would be appreciated.

Thanks.

add '\' at end

July|Month No. 7
August|Month No. 8
September|Month No. 9
October|Month No. 10
November|Month No. 11
December|Month No. 12

Thanks,
penchal

Hey penchal,

Many thanks, the magic character "\" was missing for me, great to know now.

One more question regarding this:

Independently and without use what I have in other columns, how can
I replace a field value in specific line using AWK?

Inputfile (In 3rd column all lines contain the same pattern)

January|Month No. 1|Normal month
February|Month No. 2|Normal month
March|Month No. 3|Normal month
April|Month No. 4|Normal month
May|Month No. 5|Normal month
June|Month No. 6|Normal month
July|Month No. 7|Normal month
August|Month No. 8|Normal month
September|Month No. 9|Normal month
October|Month No. 10|Normal month
November|Month No. 11|Normal month
December|Month No. 12|Normal month

I would like to replace only the first and last line in column 3 as follow:

January|Month No. 1|First month
February|Month No. 2|Normal month
March|Month No. 3|Normal month
April|Month No. 4|Normal month
May|Month No. 5|Normal month
June|Month No. 6|Normal month
July|Month No. 7|Normal month
August|Month No. 8|Normal month
September|Month No. 9|Normal month
October|Month No. 10|Normal month
November|Month No. 11|Normal month
December|Month No. 12|Last month

I�m not sure how to use the "if" and "and" conditions together. I�m trying for the first part with this code, but the result is not what I need, because this script replaces all ocurrences:

awk 'BEGIN {OFS=FS="|"; IGNORECASE=1} {if($3 && NR=1) sub(/Normal month/,"First month",$3); print}' inputfile

January|Month No. 1|First month
February|Month No. 2|First month
March|Month No. 3|First month
April|Month No. 4|First month
May|Month No. 5|First month
June|Month No. 6|First month
July|Month No. 7|First month
August|Month No. 8|First month
September|Month No. 9|First month
October|Month No. 10|First month
November|Month No. 11|First month
December|Month No. 12|First month

Then, how can I replace values for first and last lines within same AWK script?

Maybe somebody could help me with this.

Thanks in advance.

Something like this?

awk -F"|" '/Jan/{$3="First month"} /Dec/{$3="Last month"}1' OFS="|" file

Hi Franklin,

Thanks for your reply. This works, but is there a way to force awk to see
in specific line and column?

I think something like and IF statement similar to

if($3 && NR=1) 
{code to replace string}
print $0

I ask in this way because the content in other columns different to column 3 is variable depending the file I�m processing.

Thanks in advance.

nawk -F'|' 'FNR==1{$NF="somethingElse";prev=$0}{print prev;prev=$0}END{match(prev, "[^|][|]*$"); print substr(prev,1,RSTART-1) OFS "somethingElse"}' OFS='|' myFile

Thanks verseg for your help.

I�ve tested and the output It�s almost complete, but it looks that
modifies the second line and last line in different way.

*I�ve used AWK instead nawk, my cygwin doesn�t know nawk.

awk -F'|' 'FNR==1{$NF="First month";prev=$0}{print prev;prev=$0}END{match(prev, "[^|][|]*$"); print substr(prev,1,RSTART-1) OFS "Last month"}' OFS='|' Dzdi_temp

January|Month No. 1|First month
January|Month No. 1|First month --> 2nd line was modified
February|Month No. 2|Normal month
March|Month No. 3|Normal month
April|Month No. 4|Normal month
May|Month No. 5|Normal month
June|Month No. 6|Normal month
July|Month No. 7|Normal month
August|Month No. 8|Normal month
September|Month No. 9|Normal month
October|Month No. 10|Normal month
November|Month No. 11|Normal month
December|Month No. 12|Normal month|Last month-->Added a new column without replace

How to fix this?

Thanks again

A sed one:

sed "1s/\(.*\|\).*/\1First Month/;\$s/\(.*\|\).*/\1Last Month/"

The solution from Franklin52 works fine, but if mean there may be more than 3 fields (but the value to change is always in the last field), you can modify it slightly:

awk -F"|" '/Jan/{$NF="First month"} /Dec/{$NF="Last month"}1' OFS="|" file

Hello scottn,

Both solutions you gave and Franklin52�s work perfect.

The only thing is that in this case a would like to have an AWK script
to do this, in order to include it in a main AWK script.

Testing, testing and viewing the way awk assign equivalences, I get the correct code forcing awk to search and replace independently and without take like a reference the content in other columns.

It was only missing use "==" instead of "=" within the "if" statement as follow:

awk 'BEGIN {OFS=FS="|"; IGNORECASE=1} {if($3 && NR==1) sub(/normal month/,"first month");print}' file
awk 'BEGIN {OFS=FS="|"; IGNORECASE=1} {if($3 && NR==12) sub(/normal month/,"Last month");print}' file

With above script I�m able to replace first and last values in 3erd column, but separately.
Now I hope somebody may help me to improve and finish this script in this 2 last issues:

1-) How to join both awk lines within a unique AWK script?
I�ve tried with script below putting a END statement but only prints the last line:

awk 'BEGIN {OFS=FS="|"; IGNORECASE=1} 
    {if($3 && NR==1) sub(/normal month/,"first month");
     if($3 && NR==12) sub(/normal month/,"Last month")} END{print}' file

2-) I can get the total number of lines with

LastLine=$(awk 'END{print NR}' file)

, but I don�t now how to include this variable in the part that searches and replaces last line (I mean, instead of NR==12, put a variable something like NR==LastLine).

Thanks again for your kindly help.

Something like this?

awk -v lastline=$(wc -l < file) '
BEGIN {OFS=FS="|"; IGNORECASE=1} 
NR==1{...}
NR==lastline{...}
1' file
awk -F'|' 'FNR==1{$NF="something";prev=$0;next}{print prev;prev=$0}END{match(prev, "[^|][^|]*$"); print substr(prev,1,RSTART-1) "something"}' OFS='|' myFile

Great and precise. And it evaluates the last line internally, it works how I need it, perfect!

vgersh99, many thanks for your support and kindly help.