split bash variable by semicolon

  • Follow


Hi,

I need to build a bash script to access and convert a text file header 
based on a sql match in order to copy data to another table.  As so, I 
thought of awk's split as the best alternative.

Consider a bash script where:

header=$(head -1 $CAMINHO/$FICHEIRO | sed -e 's/"//g')
# header is a ';' separated CSV like line: "nad huje;am;tre saim"

I want to have: 1st element of array = nad huje
                2nd elem = am
                3rd elem = tre saim
I want to acess the header variable inside awk command.
awk '{
    search=";";
    n=split('$header',array,search);
    for (i=1;i<=n;i++) {
        printf("Word[%d]=%s\n",i,array[i]);
    }
    exit;
}  '

The problem is:
awk: cmd. line:3:     n=split(nad_huje
awk: cmd. line:3:                     ^ unexpected newline or end of string

In the search field I tried to write any character 'a' for example, but 
the split function doesn't seem to be working.

I also tried to play with FS and RS but with no success.

Can't I access the header variable inside awk like that?  Is the array 
accessible to bash after awk finishes its job?

Thank you for any help,

Luis
0
Reply Luis 2/24/2009 1:13:21 PM

On Tuesday 24 February 2009 14:13, Luis P. Mendes wrote:

> Hi,
> 
> I need to build a bash script to access and convert a text file header
> based on a sql match in order to copy data to another table.  As so, I
> thought of awk's split as the best alternative.
> 
> Consider a bash script where:
> 
> header=$(head -1 $CAMINHO/$FICHEIRO | sed -e 's/"//g')
> # header is a ';' separated CSV like line: "nad huje;am;tre saim"
> 
> I want to have: 1st element of array = nad huje
>                 2nd elem = am
>                 3rd elem = tre saim
> I want to acess the header variable inside awk command.
> awk '{
>     search=";";
>     n=split('$header',array,search);
>     for (i=1;i<=n;i++) {
>         printf("Word[%d]=%s\n",i,array[i]);
>     }
>     exit;
> }  '
> 
> The problem is:
> awk: cmd. line:3:     n=split(nad_huje
> awk: cmd. line:3:                     ^ unexpected newline or end of
> string

What you need is to use the -v option:

awk -v h="$header" '{
   search=";";
   n=split(header,array,search);
   for (i=1;i<=n;i++) {
     printf("Word[%d]=%s\n",i,array[i]);
   }
   exit;
}'

But of course you can also do all in awk:

awk '
NR==1{
   gsub(/"/,"");
   search=";";
   n=split($0,array,search);
   for (i=1;i<=n;i++) {
     printf("Word[%d]=%s\n",i,array[i]);
   }
   exit;
}' "$CAMINHO/$FICHEIRO"

0
Reply pk 2/24/2009 1:22:25 PM


Tue, 24 Feb 2009 14:22:25 +0100, pk escreveu:

> On Tuesday 24 February 2009 14:13, Luis P. Mendes wrote:
> 
>> Hi,
>> 
>> I need to build a bash script to access and convert a text file header
>> based on a sql match in order to copy data to another table.  As so, I
>> thought of awk's split as the best alternative.
>> 
>> Consider a bash script where:
>> 
>> header=$(head -1 $CAMINHO/$FICHEIRO | sed -e 's/"//g') # header is a
>> ';' separated CSV like line: "nad huje;am;tre saim"
>> 
>> I want to have: 1st element of array = nad huje
>>                 2nd elem = am
>>                 3rd elem = tre saim
>> I want to acess the header variable inside awk command. awk '{
>>     search=";";
>>     n=split('$header',array,search);
>>     for (i=1;i<=n;i++) {
>>         printf("Word[%d]=%s\n",i,array[i]);
>>     }
>>     exit;
>> }  '
>> 
>> The problem is:
>> awk: cmd. line:3:     n=split(nad_huje awk: cmd. line:3:               
>>      ^ unexpected newline or end of string
> 
> What you need is to use the -v option:
> 
> awk -v h="$header" '{
>    search=";";
>    n=split(header,array,search);
>    for (i=1;i<=n;i++) {
>      printf("Word[%d]=%s\n",i,array[i]);
>    }
>    exit;
> }'

Thank you pk, but now I have two other questions:
1- now the scripts pauses and needs a <return> to execute the awk part.  
Why is that?
2- I'd need the array Word back in bash as a bash variable.  How can I do 
it?

Luis
0
Reply Luis 2/24/2009 3:12:54 PM

On Tuesday 24 February 2009 16:12, Luis P. Mendes wrote:

>> What you need is to use the -v option:
>> 
>> awk -v h="$header" '{
>>    search=";";
>>    n=split(header,array,search);
>>    for (i=1;i<=n;i++) {
>>      printf("Word[%d]=%s\n",i,array[i]);
>>    }
>>    exit;
>> }'
> 
> Thank you pk, but now I have two other questions:
> 1- now the scripts pauses and needs a <return> to execute the awk part.
> Why is that?

Because you did not specify an input file:

awk -v h="$header" '.....' "$CAMINHO/$FICHEIRO"

> 2- I'd need the array Word back in bash as a bash variable.  How can I do
> it?

Then (OT here but anyway) you can just use bash only:

oifs=$IFS
IFS=';'
array=( $(head -n 1 "$CAMINHO/$FICHEIRO" | sed -e 's/"//g') )
IFS=$oifs

0
Reply pk 2/24/2009 3:30:40 PM

On Feb 24, 7:22=A0am, pk <p...@pk.invalid> wrote:
> On Tuesday 24 February 2009 14:13, Luis P. Mendes wrote:
>
>
>
> > Hi,
>
> > I need to build a bash script to access and convert a text file header
> > based on a sql match in order to copy data to another table. =A0As so, =
I
> > thought of awk's split as the best alternative.
>
> > Consider a bash script where:
>
> > header=3D$(head -1 $CAMINHO/$FICHEIRO | sed -e 's/"//g')
> > # header is a ';' separated CSV like line: "nad huje;am;tre saim"
>
> > I want to have: 1st element of array =3D nad huje
> > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 2nd elem =3D am
> > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 3rd elem =3D tre saim
> > I want to acess the header variable inside awk command.
> > awk '{
> > =A0 =A0 search=3D";";
> > =A0 =A0 n=3Dsplit('$header',array,search);
> > =A0 =A0 for (i=3D1;i<=3Dn;i++) {
> > =A0 =A0 =A0 =A0 printf("Word[%d]=3D%s\n",i,array[i]);
> > =A0 =A0 }
> > =A0 =A0 exit;
> > } =A0'
>
> > The problem is:
> > awk: cmd. line:3: =A0 =A0 n=3Dsplit(nad_huje
> > awk: cmd. line:3: =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 ^ unexpected =
newline or end of
> > string
>
> What you need is to use the -v option:
>
> awk -v h=3D"$header" '{
> =A0 =A0search=3D";";
> =A0 =A0n=3Dsplit(header,array,search);
> =A0 =A0for (i=3D1;i<=3Dn;i++) {
> =A0 =A0 =A0printf("Word[%d]=3D%s\n",i,array[i]);
> =A0 =A0}
> =A0 =A0exit;
>
> }'
>
> But of course you can also do all in awk:
>
> awk '
> NR=3D=3D1{
> =A0 =A0gsub(/"/,"");
> =A0 =A0search=3D";";
> =A0 =A0n=3Dsplit($0,array,search);
> =A0 =A0for (i=3D1;i<=3Dn;i++) {
> =A0 =A0 =A0printf("Word[%d]=3D%s\n",i,array[i]);
> =A0 =A0}
> =A0 =A0exit;
>
> }' "$CAMINHO/$FICHEIRO"
>
>

No need for split() (or spurious semicolons and braces):

awk -F';' '
NR=3D=3D1{
   gsub(/"/,"")
   for (i=3D1;i<=3DNF;i++)
     printf "Word[%d]=3D%s\n",i,$i
   exit
}' "$CAMINHO/$FICHEIRO"

   Ed.
0
Reply Ed 2/24/2009 5:06:18 PM

On Feb 24, 9:30=A0am, pk <p...@pk.invalid> wrote:
> On Tuesday 24 February 2009 16:12, Luis P. Mendes wrote:
>
> >> What you need is to use the -v option:
>
> >> awk -v h=3D"$header" '{
> >> =A0 =A0search=3D";";
> >> =A0 =A0n=3Dsplit(header,array,search);
> >> =A0 =A0for (i=3D1;i<=3Dn;i++) {
> >> =A0 =A0 =A0printf("Word[%d]=3D%s\n",i,array[i]);
> >> =A0 =A0}
> >> =A0 =A0exit;
> >> }'
>
> > Thank you pk, but now I have two other questions:
> > 1- now the scripts pauses and needs a <return> to execute the awk part.
> > Why is that?
>
> Because you did not specify an input file:
>
> awk -v h=3D"$header" '.....' "$CAMINHO/$FICHEIRO"
>
> > 2- I'd need the array Word back in bash as a bash variable. =A0How can =
I do
> > it?
>
> Then (OT here but anyway) you can just use bash only:
>
> oifs=3D$IFS
> IFS=3D';'
> array=3D( $(head -n 1 "$CAMINHO/$FICHEIRO" | sed -e 's/"//g') )
> IFS=3D$oifs

No need for head and pipe:

oifs=3D$IFS
IFS=3D';'
array=3D( $(sed -n '1 s/"//g p' "$CAMINHO/$FICHEIRO") )
IFS=3D$oifs

or, more topically:

oifs=3D$IFS
IFS=3D';'
array=3D( $(awk 'NR=3D=3D1{gsub(/"/,""); print; exit}' "$CAMINHO/
$FICHEIRO") )
IFS=3D$oifs

I expect there's a way to make sed exit after processing that first
line if efficiency's a concern - follow up at comp.unix.shell or
similar if necessary.

   Ed.
0
Reply Ed 2/24/2009 7:07:37 PM

On Tuesday 24 February 2009 20:07, Ed Morton wrote:

>> Then (OT here but anyway) you can just use bash only:
>>
>> oifs=$IFS
>> IFS=';'
>> array=( $(head -n 1 "$CAMINHO/$FICHEIRO" | sed -e 's/"//g') )
>> IFS=$oifs
> 
> No need for head and pipe:
> 
> oifs=$IFS
> IFS=';'
> array=( $(sed -n '1 s/"//g p' "$CAMINHO/$FICHEIRO") )
> IFS=$oifs
> 
> or, more topically:
> 
> oifs=$IFS
> IFS=';'
> array=( $(awk 'NR==1{gsub(/"/,""); print; exit}' "$CAMINHO/
> $FICHEIRO") )
> IFS=$oifs

Right, thanks (also for the other correction). I was more focused on the
array part of the question than fixing other things.

0
Reply pk 2/24/2009 9:09:12 PM

pk wrote:
> On Tuesday 24 February 2009 14:13, Luis P. Mendes wrote:
> 
> 
>>Hi,
>>
>>I need to build a bash script to access and convert a text file header
>>based on a sql match in order to copy data to another table.  As so, I
>>thought of awk's split as the best alternative.
>>
>>Consider a bash script where:
>>
>>header=$(head -1 $CAMINHO/$FICHEIRO | sed -e 's/"//g')
>># header is a ';' separated CSV like line: "nad huje;am;tre saim"
>>
>>I want to have: 1st element of array = nad huje
>>                2nd elem = am
>>                3rd elem = tre saim
>>I want to acess the header variable inside awk command.
>>awk '{
>>    search=";";
>>    n=split('$header',array,search);
>>    for (i=1;i<=n;i++) {
>>        printf("Word[%d]=%s\n",i,array[i]);
>>    }
>>    exit;
>>}  '
>>
>>The problem is:
>>awk: cmd. line:3:     n=split(nad_huje
>>awk: cmd. line:3:                     ^ unexpected newline or end of
>>string
> 
> 
> What you need is to use the -v option:
> 
> awk -v h="$header" '{
>    search=";";
>    n=split(header,array,search);

I suppose you meant...

      n=split(h,array,search)


Janis

>    for (i=1;i<=n;i++) {
>      printf("Word[%d]=%s\n",i,array[i]);
>    }
>    exit;
> }'
> 
> But of course you can also do all in awk:
> 
> awk '
> NR==1{
>    gsub(/"/,"");
>    search=";";
>    n=split($0,array,search);
>    for (i=1;i<=n;i++) {
>      printf("Word[%d]=%s\n",i,array[i]);
>    }
>    exit;
> }' "$CAMINHO/$FICHEIRO"
> 
0
Reply Janis 2/24/2009 9:57:33 PM

7 Replies
510 Views

(page loaded in 0.087 seconds)

Similiar Articles:













7/22/2012 12:29:11 PM


Reply: