awk multiple fields separators

Can you please help me with this ....

Input File

 
share "FTPTransfer" "/v31_fs01/root/FTP-Transfer" umask=022 maxusr=4294967295 netbios=NJ09FIL530
share "Test" "/v31_fs01/root/Test" umask=022 maxusr=4294967295 netbios=NJ09FIL530
share "ENR California" "/v31_fs01/root/ENR California" umask=022 maxusr=4294967295 netbios=NJ09FIL530
share "ENR Midwest" "/v31_fs01/root/ENR Midwest" umask=022 maxusr=4294967295 netbios=NJ09FIL530
 

Output Needed

 
v31_fs01,[FTPTransfer](NJ09FIL530),[/v31_fs01/root/FTP-Transfer]
v31_fs01,[Test](NJ09FIL530),[/v31_fs01/root/Test]
v31_fs01,[ENR California](NJ09FIL530),[/v31_fs01/root/ENR California]
v31_fs01,[ENR Midwest](NJ09FIL530),[/v31_fs01/root/ENR Midwest]
 

1st field is the one right after the first "/"
2nd field is a combination of between the first set of "" and the data right next to NetBIOS=
3rd field is data between second set of ""

Thanks !

A perlish solution:

$ perl -ne '
  @F = m{^[^"]+"([^"]+)"\s+"(/([^/"]+)[^"]*)".*netbios=(\S+)}i;
  print $F[2], ",[", $F[0], "](", $F[3], "),[", $F[1], "]\n";
' file
v31_fs01,[FTPTransfer](NJ09FIL530),[/v31_fs01/root/FTP-Transfer]
v31_fs01,[Test](NJ09FIL530),[/v31_fs01/root/Test]
v31_fs01,[ENR California](NJ09FIL530),[/v31_fs01/root/ENR California]
v31_fs01,[ENR Midwest](NJ09FIL530),[/v31_fs01/root/ENR Midwest]

(lines split for easier reading)

works grt ...! any possibility with AWK ?

Something like:

BEGIN {
  FS = "\" \"|\" | \""; 
  OFS = ",";
}

{
  split($3, P, "/");

  N = "<unknown>"; # netbios name
  n = split($4, A, "[ =]");
  for (i = 1; i <= n; i += 2) { if (A == "netbios") N = A[i+1]; }

  print P[2], "[" $2 "]", "(" N ")", "[" $3 "]";
}

For given sample input this will work

Either setting FS

awk -F'"|=' '{split($4,A,/\//); print A[2],"["$2"]("$NF")","["$4"]"}' OFS=, infile

OR lengthy match

awk '{print substr($0,match($0,/"\/[^"\/]*/)+2,RLENGTH-2), "["substr($0,match($0,/"[^"]*"/)+1,RLENGTH-2)"]("substr($0,match($0,/[^netbios=]*$/))")","["substr($0,match($0,/"\/[^"]*/)+1,RLENGTH-1)"]"}' OFS=, infile
awk '
     {
	f1 = substr($0,match($0,/"\/[^"\/]*/)+2,RLENGTH-2)
	f2 = sprintf("[%s](%s)",substr($0,match($0,/"[^"]*"/)+1,RLENGTH-2),substr($0,match($0,/[^netbios=]*$/)))
	f3 = sprintf("[%s]",substr($0,match($0,/"\/[^"]*/)+1,RLENGTH-1))
	
	print f1,f2,f3
     } 
    ' OFS=, infile

How about this ..derekludwig

 
export "/0014apps" name="/reet" root=10.200.12.29:10.200.12.32 access=10.200.12.29:10.200.12.32
export "/0016apps" ro=10.202.140.3 root=10.202.140.34:10.202.140.37 access=10.202.140.34:10.202.140.37 
export "/tech_st" root=10.202.98.59 rw=10.202.98.5 access=10.202.98.59 
 

Output

[/0014apps],[/reet],[10.200.12.29:10.200.12.32],[10.200.12.29:10.200.12.32],,
[/0016apps],,[10.202.140.34:10.202.140.37],[10.202.140.34:10.202.140.37],[10.202.140.3],
[/tech_st],,[10.202.98.59],[10.202.98.59],,[10.202.98.5]

Where $1=path
$2="name="
$3="root="
$4="access="
$5="ro="
$6="rw="
Empty space for missing fields ... order of fields may be different
THanks again !!

It does not help leaving the windows <CR> line separators in your sample. Get rid of them first.

Then try

awk     'BEGIN          {nK=split ("name root access ro rw", K)}
                        {gsub (/"/,"")
                         for (i=3; i<=NF; i++) {split($i, T, "="); O[T[1]]=T[2]}

                         printf "[%s]", $2
                         for (i=1; i<=nK; i++) printf ",%s", O[K]?"["O[K]"]":""
                         printf "\n"
                         delete O
                        }
        ' file
[/0014apps],[/reet],[10.200.12.29:10.200.12.32],[10.200.12.29:10.200.12.32],,
[/0016apps],,[10.202.140.34:10.202.140.37],[10.202.140.34:10.202.140.37],[10.202.140.3],
[/tech_st],,[10.202.98.59],[10.202.98.59],,[10.202.98.5]

Thanks RudiC ,

Works fine with GAWK ... but with NAWK I get this error

 
 nawk: you can only delete array[element] at source line 9
 context is
                                 delete O >>> 
 <<<                         }
nawk: syntax error at source line 9
nawk: illegal statement at source line 9

I did fix the <CR>

Thanks !

---------- Post updated at 05:28 AM ---------- Previous update was at 04:26 AM ----------

I tried this instead to clear out the array instead of delete

 
 split("", O)
 

Looks like its working ...

Have a question ... how do i get the complete 2nd field between commas if it has spaces in it

for ex

export "/0014apps test" name="/reet" root=10.200.12.29:10.200.12.32 access=10.200.12.29:10.200.12.32

with this code ... the space gets skipped

awk     'BEGIN          {nK=split ("name root access ro rw", K)}
                        {gsub (/"/,"")
                         for (i=3; i<=NF; i++) {split($i, T, "="); O[T[1]]=T[2]}

                         printf "[%s]", $2
                         for (i=1; i<=nK; i++) printf ",%s", O[K]?"["O[K]"]":""
                         printf "\n"
                         delete O
                        }
        ' file

output

[/0014apps],[/reet],[10.200.12.29:10.200.12.32],[10.200.12.29:10.200.12.32],,

thanks!!

xargs understands quotes, so can be used to separate records which are annoying to handle other ways.

xargs -n 1 < inputfile | awk 'NR==2'

thanks ! ... but I am not sure how would I use xargs in the above script .
The script works fine ... and gives me the right output ..except few records in the input file have space between the "" .. for example in the above example

the output should be

 
 [/0014apps test],[/reet],[10.200.12.29:10.200.12.32],[10.200.12.29:10.200.12.32],,
 

instead of

 
  [/0014apps],[/reet],[10.200.12.29:10.200.12.32],[10.200.12.29:10.200.12.32],,
 

Thanks !

Still cannot figure out how to get the complete field for first column including spaces

export "/0014apps/test folder" name="/reet" root=10.200.12.29:10.200.12.32 access=10.200.12.29:10.200.12.32
export "/0016apps" ro=10.202.140.3 root=10.202.140.34:10.202.140.37 access=10.202.140.34:10.202.140.37 
export "/tech_st" root=10.202.98.59 rw=10.202.98.5 access=10.202.98.59 

Output needed

[/0014apps/test folder],[/reet],[10.200.12.29:10.200.12.32],[10.200.12.29:10.200.12.32],,
[/0016apps],,[10.202.140.34:10.202.140.37],[10.202.140.34:10.202.140.37],[10.202.140.3],
[/tech_st],,[10.202.98.59],[10.202.98.59],,[10.202.98.5]
 
 awk     'BEGIN          {nK=split ("name root access ro rw", K)}
                        {gsub (/"/,"")
                         for (i=3; i<=NF; i++) {split($i, T, "="); O[T[1]]=T[2]}

                         printf "[%s]", $2
                         for (i=1; i<=nK; i++) printf ",%s", O[K]?"["O[K]"]":""
                         printf "\n"
                         delete O
                        }
        ' file
 
[/0014apps],[/reet],[10.200.12.29:10.200.12.32],[10.200.12.29:10.200.12.32],,
[/0016apps],,[10.202.140.34:10.202.140.37],[10.202.140.34:10.202.140.37],[10.202.140.3],
[/tech_st],,[10.202.98.59],[10.202.98.59],,[10.202.98.5]
 

Thanks !

The problem is the field separator occurs in the field. For example:

export "/0014apps/test folder" name="/reet" root=10.200.12.29:10.200.12.32 access=10.200.12.29:10.200.12.32

to be split into

$1: export
$2: "/0014apps/test
$3: folder"
$4: name="/reet"
$5: root=10.200.12.29:10.200.12.32
$6: access=10.200.12.29:10.200.12.32

What is needed is a field separator that takes into account the quoted string - to be able to split the line into what is needed. Don't think awk is up to the task, so use perl:

use strict;
use warnings;

$, = ',';
$\ = "\n";

my @K = qw{ name root access ro rw };

while (<>) {
  chomp;
  my @F = m{(?:[^ "]|"[^"]+")+}g;

  shift @F; # get rid of the export

  my $dir = shift @F;
     $dir =~ s{"}{}g;

  my %O = ();

  for (@F) {
    my ($k, $v) = split /=/;
    next unless defined $v;
    $v =~ s{"}{}g;
    $O{$k} = $v;
  }

  print '[' . $dir . ']', map { defined $O{$_} ? '[' . $O{$_} . ']' : '' } @K;
}

Which results in

[/0014apps/test folder],[/reet],[10.200.12.29:10.200.12.32],[10.200.12.29:10.200.12.32],,
[/0014apps],[/reet],[10.200.12.29:10.200.12.32],[10.200.12.29:10.200.12.32],,
[/0016apps],,[10.202.140.34:10.202.140.37],[10.202.140.34:10.202.140.37],[10.202.140.3],
[/tech_st],,[10.202.98.59],[10.202.98.59],,[10.202.98.5]

I would be curious to know if there is an awkish solution.

Side note, I have to ask - why the square-braces?

the square brackets are just cosmetic .... optional I guess

Thanks again !!

---------- Post updated at 06:58 AM ---------- Previous update was at 06:43 AM ----------

quick question ... I missed another field in the input , not good at perl ... how can I add it

export "/0014apps/test folder" name="/reet" root=10.200.12.29:10.200.12.32 access=10.200.12.29:10.200.12.32 comment="test folder,finance/HR"
export "/0016apps" ro=10.202.140.3 root=10.202.140.34:10.202.140.37 access=10.202.140.34:10.202.140.37 comment="A&E group-NJ"

output

 
 [/0014apps/test folder],[/reet],[10.200.12.29:10.200.12.32],[10.200.12.29:10.200.12.32],,[test folder,finance/HR]
[/0016apps],,[10.202.140.34:10.202.140.37],[10.202.140.34:10.202.140.37],[10.202.140.3],[A&E group-NJ]
 

Thanks !

Change the definition of @K to:

my @K = qw{ name root access ro rw comment };

If the square braces are cosmetic, then change the print to:

print $dir, map { defined $O{$_} ? $O{$_} : '' } @K;

which can easily be imported into excel. If you need column headers, add the following just before the while-loop:

print 'dir', @K;