The last argument contains spaces, how do I get it into a variable?

Gooday
I have an argument string that contains 15 arguments.
The first 14 arguments are easy to handle because they are separated by spaces

ARG14=`echo ${ARGSTRING} | awk '{print $14}'`

The last argument is a text that may be empty or contain spaces. So any ideas on how I get the last argument into the variable ARG15? ie delete from $ARG14 to the beginning of line will be greately appreciated.

regards

Zagga

Something like this?

ARG15=`echo ${ARGSTRING} | awk '{sub(".*" $14 FS,x)}1'`
1 Like

Thanks very much Franklin52, your solution works fine while arguments 14 and 15 are populated. Unfortunately I omitted to mention that these fields are optional.
After testing: if Arg14 and Arg15 are null, then Arg15 contains the same value as Arg13.
If Arg15 only is null, the it recuperates the value of Arg14.
I figured I would add tests on each field to set to "NONE" if null, unless you have a better trick up your sleeve?

Regards

Zagga

Do you have 2 spaces (field separators) at the end of the line if the last 2 fields are empty?

NO in fact I have 56 spaces at the end of the record. But the good news is the last two fields are fixed length which is not the case of all the preceding fields. Arg14= 4 cars Arg15=50 cars + 2 FS=56.

So I need to get from the end of $Arg13 to the EoL into a new variable and then I should be able to cut Arg14 and 15 from their positions.

Can you do a cut backwards from the end of line?

Any ideas welcome?

Zagga

Try this:

Arg14=`echo ${ARGSTRING} | awk '{print substr($14, 1 ,4)}'`

Arg15=`echo ${ARGSTRING} | awk '{print substr($14, 5 ,50)}'`

Sorry Franklin52 that doesn't seem to work:

Case 1:
if both $14 and 15 are null ie full of spaces.
I get Arg14=" " and Arg15 has nothing.

Case 2:
if $14="3333" and $15 is null
I get Arg14="3333" and Arg15 has nothing.

Case 3:
if $14 is null ie " " and $15 contains "12345678901234567890123456789012345678901234567890"
I get Arg14="1234" and Arg15="567890......"

Case 4:
If $14="9999" and $15="one two three four five six seven ....."
I get Arg14="9999" and Arg15=

I think I need to create an intermediary variable and get everything from the end of $13 into it.

I'm not sure I've made myself clear.

Thanks in advance

Zagga

---------- Post updated at 11:51 AM ---------- Previous update was at 11:39 AM ----------

The reply I just posted may have been a little misleading as I quoted ARG14 but not ARG15. so output looked different. As it turns out Case 1 and 2 give expected results. Case 3 and 4 don't.
Zagga

The simple way is to post the sample source data, and your expect output

Could you be more exact with your example input? When you say $14 and $15 do you mean what awk thinks they are, or what they''re supposed to be?

Also, null and spaces are not the same thing (and the number of spaces is important as well).

Thanks for your interest guys:

Below is the script instruction intended to recuperate Arguments 13 (4 cars) and 14 (50 cars).
Arguments 1-12 are variable length and separated by a space.

V_SEVERITY=`echo ${} | awk '{print substr($13,1,4)}'`
V_INFO=`echo ${
} | awk '{print substr($13,5,50)}'`

Case 1:

${*} = "UNIV ABORTED JOB  GS1 VMSDLCEREF 2011/10/24 11:59 0000183 0000000 UNIV56 X vmsdlceref                                                        "

Note the quotes are mine.

Result of echo:
V_SEVERITY=""
V_INFO=""

Case 2:

${*} = "UNIV ABORTED JOB  GS2 VMSDLCEREF 2011/10/24 12:08 0000184 0000000 UNIV56 X vmsdlceref 3333 
                                                  "

V_SEVERITY="3333"
V_INFO=""

Case 3:

${*} = "UNIV ABORTED JOB  GS3 VMSDLCEREF 2011/10/24 12:12 0000185 0000000 UNIV56 X vmsdlceref      12345678901234567890123456789012345678901234567890"

V_SEVERITY="1234"
V_INFO="5678901234567890123456789012345678901234567890"

Case 4:

${*} = "UNIV ABORTED JOB  GS4 VMSDLCEREF 2011/10/24 12:14 0000186 0000000 UNIV56 X vmsdlceref 9999 one two three four five six seven eight nine ten X"

V_SEVERITY="9999"
V_INFO=""

Sorry in Case 1 the argument string has 56 spaces at the end and in Case 2 51, the forul software seems to trim the spaces.

Zagga

Try this...

V_SEVERITY=$(echo $*| awk 'NF>=13{if($13 ~ /[0-9]*/)print substr($13,0,4)}')
V_INFO=$(echo $*| awk 'NF>=13{if($13 ~ /[0-9]*/)print substr($13,5)}')

--ahamed

Use code tags.

How many spaces are there after vmsdlceref in case 3?

Ahamed, CarloM

I still have the same problem in cases 3 and 4 using Ahamed's proposed solution:

If argument 13 is empty, there will be FS+4 spaces + FS (ie 6 spaces in all).
In case three, the variable V_SEVERITY recuperates the 1st four characters of ARG14 where it should contain all spaces.

Zagga

I am confused now!
Whatever you have posted, isn't that you want? or are those the error conditions? Please provide some more clarity!

--ahamed

Ahamed

In all there are 14 arguments. The first 12 arguments are variable in length but are separated by single space characters, so they pose no problems.
Arguments 13 and 14 are optional, when not populated they are padded with spaces.
Argument 13 is 4 characters longs and Argument 14 is 50 characters long.
So expected results are as follows:

Case 1:
V_SEVERITY=""
V_INFO=""

CAse 2:
V_SEVERITY="3333"
V_INFO=""

Case 3:
V_SEVERITY=""
V_INFO="123456789012345678901234567890123456789etc"

Case 4:
V_SEVERITY="9999"
V_INFO="one two three four five six seven eight nine ten X"

Hope that has lifted the confusion?

Zagga

Actually, it doesn't matter.

Try this...

V_SEVERITY=$(echo $*| awk 'NF>=13{if(length($13)==4){print $13}}')
V_INFO=$(echo $*|awk 'NF>=13{print($14)?substr($0,index($0,length($13)==4?($14?$14:$13):$13)):
length($13)==4?"":$13}'

--ahamed

Actually, if you have gawk you can just use match (which doesn't have to rely on the values, you can just grab the last 2 fixed length fields). Something like:

# cat xx.txt
UNIV ABORTED JOB  GS1 VMSDLCEREF 2011/10/24 11:59 0000183 0000000 UNIV56 X vmsdlceref
UNIV ABORTED JOB  GS2 VMSDLCEREF 2011/10/24 12:08 0000184 0000000 UNIV56 X vmsdlceref 3333
UNIV ABORTED JOB  GS3 VMSDLCEREF 2011/10/24 12:12 0000185 0000000 UNIV56 X vmsdlceref      12345678901234567890123456789012345678901234567890
UNIV ABORTED JOB  GS4 VMSDLCEREF 2011/10/24 12:14 0000186 0000000 UNIV56 X vmsdlceref 9999 one two three four five six seven eight nine ten X
# gawk --re-interval '{ matched=match($0," (.{4}) (.{50})$", myarray); if (matched) { printf ("[%s][%s]\n", myarray[1],myarray[2]);}}' xx.txt
[    ][                                                  ]
[3333][                                                  ]
[    ][12345678901234567890123456789012345678901234567890]
[9999][one two three four five six seven eight nine ten X]

which I should have thought of earlier since I was doing something similar just the other day, but there you go... :slight_smile:

@CarlM
Pretty neat work :slight_smile:
Honestly, I didn't know that match function took a 3rd argument...

--ahamed

Easy.

read A1 A2 A3 A4 A5 A6 A7 A8 A9 AA AB AC AD AE AF <"$FILE"