Skip to main content
added 545 characters in body
Source Link
Sundeep
  • 12.2k
  • 3
  • 28
  • 73

With awk (tested with GNU awk, not sure if it works with other implementations)

$ cat kv.awk
/appID/ {
    for (i = 1; i <= NF; i++) {
        $i ~ /^port=/ && (a = $i)
        $i ~ /^authenticate=/ && (b = $i)
        $i ~ /^appID=/ && (c = $i)
    }
    print NR "\n" a, b, c
}

$ awk -v OFS='\t' -f kv.awk ip.txt
1
port=1234   authenticate=true   appID=dummyAppId1
2
port=1244   authenticate=false  appID=dummyAppId2
3
port=1235   authenticate=true   appID=dummyAppId3


With perl

$ # note that the order is changed for second line here
$ cat ip.txt
process1 port=1234 authenticate=true appID=dummyAppId1 <some more params>
process3 port=1244 appID=dummyAppId2 authenticate=false <some more params>
process2 port=1235 authenticate=true appID=dummyAppId3 <some more params>

$ perl -lpe 's/(?=.*(port=[^ ]+))(?=.*(authenticate=[^ ]+))(?=.*(appID=[^ ]+)).*/$1\t$2\t$3/; print $.' ip.txt 
1
port=1234   authenticate=true   appID=dummyAppId1
2
port=1244   authenticate=false  appID=dummyAppId2
3
port=1235   authenticate=true   appID=dummyAppId3
  • (?=.*(port=[^ ]+)) first capture group for port
  • (?=.*(authenticate=[^ ]+)) second capture group for authenticate and so on
  • print $. for line number
  • To avoid partial matches, use \bport, \bappID etc if word boundary is enough. Otherwise, use (?<!\S)(port=[^ ]+) to restrict based on whitespace.

If you need to print only lines containing appID or any other such condition, change -lpe to -lne and change print $. to print "$.\n$_" if /appID/

With perl

$ # note that the order is changed for second line here
$ cat ip.txt
process1 port=1234 authenticate=true appID=dummyAppId1 <some more params>
process3 port=1244 appID=dummyAppId2 authenticate=false <some more params>
process2 port=1235 authenticate=true appID=dummyAppId3 <some more params>

$ perl -lpe 's/(?=.*(port=[^ ]+))(?=.*(authenticate=[^ ]+))(?=.*(appID=[^ ]+)).*/$1\t$2\t$3/; print $.' ip.txt 
1
port=1234   authenticate=true   appID=dummyAppId1
2
port=1244   authenticate=false  appID=dummyAppId2
3
port=1235   authenticate=true   appID=dummyAppId3
  • (?=.*(port=[^ ]+)) first capture group for port
  • (?=.*(authenticate=[^ ]+)) second capture group for authenticate and so on
  • print $. for line number
  • To avoid partial matches, use \bport, \bappID etc if word boundary is enough. Otherwise, use (?<!\S)(port=[^ ]+) to restrict based on whitespace.

If you need to print only lines containing appID or any other such condition, change -lpe to -lne and change print $. to print "$.\n$_" if /appID/

With awk (tested with GNU awk, not sure if it works with other implementations)

$ cat kv.awk
/appID/ {
    for (i = 1; i <= NF; i++) {
        $i ~ /^port=/ && (a = $i)
        $i ~ /^authenticate=/ && (b = $i)
        $i ~ /^appID=/ && (c = $i)
    }
    print NR "\n" a, b, c
}

$ awk -v OFS='\t' -f kv.awk ip.txt
1
port=1234   authenticate=true   appID=dummyAppId1
2
port=1244   authenticate=false  appID=dummyAppId2
3
port=1235   authenticate=true   appID=dummyAppId3


With perl

$ # note that the order is changed for second line here
$ cat ip.txt
process1 port=1234 authenticate=true appID=dummyAppId1 <some more params>
process3 port=1244 appID=dummyAppId2 authenticate=false <some more params>
process2 port=1235 authenticate=true appID=dummyAppId3 <some more params>

$ perl -lpe 's/(?=.*(port=[^ ]+))(?=.*(authenticate=[^ ]+))(?=.*(appID=[^ ]+)).*/$1\t$2\t$3/; print $.' ip.txt 
1
port=1234   authenticate=true   appID=dummyAppId1
2
port=1244   authenticate=false  appID=dummyAppId2
3
port=1235   authenticate=true   appID=dummyAppId3
  • (?=.*(port=[^ ]+)) first capture group for port
  • (?=.*(authenticate=[^ ]+)) second capture group for authenticate and so on
  • print $. for line number
  • To avoid partial matches, use \bport, \bappID etc if word boundary is enough. Otherwise, use (?<!\S)(port=[^ ]+) to restrict based on whitespace.

If you need to print only lines containing appID or any other such condition, change -lpe to -lne and change print $. to print "$.\n$_" if /appID/

added 155 characters in body
Source Link
Sundeep
  • 12.2k
  • 3
  • 28
  • 73

With perl

$ # note that the order is changed for second line here
$ cat ip.txt
process1 port=1234 authenticate=true appID=dummyAppId1 <some more params>
process3 port=1244 appID=dummyAppId2 authenticate=false <some more params>
process2 port=1235 authenticate=true appID=dummyAppId3 <some more params>

$ perl -lpe 's/(?=.*(port=[^ ]+))(?=.*(authenticate=[^ ]+))(?=.*(appID=[^ ]+)).*/$1\t$2\t$3/; print $.' ip.txt 
1
port=1234   authenticate=true   appID=dummyAppId1
2
port=1244   authenticate=false  appID=dummyAppId2
3
port=1235   authenticate=true   appID=dummyAppId3
  • (?=.*(port=[^ ]+)) first capture group for port
  • (?=.*(authenticate=[^ ]+)) second capture group for authenticate and so on
  • print $. for line number
  • To avoid partial matches, use \bport, \bappID etc if word boundary is enough. Otherwise, use (?<!\S)(port=[^ ]+) to restrict based on whitespace.

If you need to print only lines containing appID or any other such condition, change -lpe to -lne and change print $. to print "$.\n$_" if /appID/

With perl

$ # note that the order is changed for second line here
$ cat ip.txt
process1 port=1234 authenticate=true appID=dummyAppId1 <some more params>
process3 port=1244 appID=dummyAppId2 authenticate=false <some more params>
process2 port=1235 authenticate=true appID=dummyAppId3 <some more params>

$ perl -lpe 's/(?=.*(port=[^ ]+))(?=.*(authenticate=[^ ]+))(?=.*(appID=[^ ]+)).*/$1\t$2\t$3/; print $.' ip.txt 
1
port=1234   authenticate=true   appID=dummyAppId1
2
port=1244   authenticate=false  appID=dummyAppId2
3
port=1235   authenticate=true   appID=dummyAppId3
  • (?=.*(port=[^ ]+)) first capture group for port
  • (?=.*(authenticate=[^ ]+)) second capture group for authenticate and so on
  • print $. for line number

If you need to print only lines containing appID or any other such condition, change -lpe to -lne and change print $. to print "$.\n$_" if /appID/

With perl

$ # note that the order is changed for second line here
$ cat ip.txt
process1 port=1234 authenticate=true appID=dummyAppId1 <some more params>
process3 port=1244 appID=dummyAppId2 authenticate=false <some more params>
process2 port=1235 authenticate=true appID=dummyAppId3 <some more params>

$ perl -lpe 's/(?=.*(port=[^ ]+))(?=.*(authenticate=[^ ]+))(?=.*(appID=[^ ]+)).*/$1\t$2\t$3/; print $.' ip.txt 
1
port=1234   authenticate=true   appID=dummyAppId1
2
port=1244   authenticate=false  appID=dummyAppId2
3
port=1235   authenticate=true   appID=dummyAppId3
  • (?=.*(port=[^ ]+)) first capture group for port
  • (?=.*(authenticate=[^ ]+)) second capture group for authenticate and so on
  • print $. for line number
  • To avoid partial matches, use \bport, \bappID etc if word boundary is enough. Otherwise, use (?<!\S)(port=[^ ]+) to restrict based on whitespace.

If you need to print only lines containing appID or any other such condition, change -lpe to -lne and change print $. to print "$.\n$_" if /appID/

Source Link
Sundeep
  • 12.2k
  • 3
  • 28
  • 73

With perl

$ # note that the order is changed for second line here
$ cat ip.txt
process1 port=1234 authenticate=true appID=dummyAppId1 <some more params>
process3 port=1244 appID=dummyAppId2 authenticate=false <some more params>
process2 port=1235 authenticate=true appID=dummyAppId3 <some more params>

$ perl -lpe 's/(?=.*(port=[^ ]+))(?=.*(authenticate=[^ ]+))(?=.*(appID=[^ ]+)).*/$1\t$2\t$3/; print $.' ip.txt 
1
port=1234   authenticate=true   appID=dummyAppId1
2
port=1244   authenticate=false  appID=dummyAppId2
3
port=1235   authenticate=true   appID=dummyAppId3
  • (?=.*(port=[^ ]+)) first capture group for port
  • (?=.*(authenticate=[^ ]+)) second capture group for authenticate and so on
  • print $. for line number

If you need to print only lines containing appID or any other such condition, change -lpe to -lne and change print $. to print "$.\n$_" if /appID/