Reputation: 1
I have a file as below:
ID: 1
Name: Admin1
Class: Administrator
Class: Leader
AliasName: User1
AliasedObject: Administrator,Admin1
ID: 2
Name: Admin2
Class: Administrator
Class: Leader
AliasName: User2
AliasedObject: Administrator,Admin2
ID: 3
Name: Admin3
Class: Administrator
Class: Leader
AliasName: User3
AliasedObject: Administrator,Admin3
Now I have to filter only the AliasName and AliasedObject as below:
AliasName AliasedObject
User1 Administrator,Admin1
User2 Administrator,Admin2
User3 Administrator,Admin3
How can I do this in Unix using the AWK/SED commands?
Upvotes: 0
Views: 87
Reputation: 5337
#!/usr/bin/perl -ln
BEGIN{ $/=''; print "AliasName\tAliasedObject";}
%F = m/(?:^|\n)(\S+):\s*(.*)/g;
print "$F{AliasName} $F{AliasedObject}"
This way, some of the fields can be empty, absent or written in a different order.
Upvotes: 0
Reputation: 203169
Whenever you have data that includes name=value pairs, it's a good idea to create a name2value array and access the fields by their names, e.g.:
$ cat tst.awk
BEGIN {
RS=""; FS="\n"; OFS="\t"
numNames = split("AliasName AliasedObject",names,/ /)
for (i=1; i<=numNames; i++) {
printf "%s%s", names[i], (i<numNames?OFS:ORS)
}
}
{
delete n2v
for (i=1;i<=NF;i++) {
name = gensub(/:.*/,"","",$i)
value = gensub(/[^:]+:\s*/,"","",$i)
n2v[name] = value
}
for (i=1; i<=numNames; i++) {
printf "%s%s", n2v[names[i]], (i<numNames?OFS:ORS)
}
}
$ awk -f tst.awk file
AliasName AliasedObject
User1 Administrator,Admin1
User2 Administrator,Admin2
User3 Administrator,Admin3
That way if you want to add additional fields to be printed later you just change split("AliasName AliasedObject",names,/ /)
to split("AliasName AliasedObject Class",names,/ /)
or whatever (but having 2 different fields both named "Class" in your data would be an issue you should fix at source if that really exists in your data).
The above uses GNU awk for a couple of extensions (delete array
, gensub()
, and \s
), but is easily tweaked to work for any awk if necessary.
While the above is the best approach in general, for this particular case if your input file values contain no blanks, I'd just use @fedorqui's concise solution: https://stackoverflow.com/a/29698956/1745001.
Upvotes: 4
Reputation: 289495
Supposing the file is exactly like this, you can set the record separator to the paragraph (that is, RS=""
, thanks Ed Morton) and then get the blocks with some data:
awk 'BEGIN{RS=""; print "AliasName","AliasedObject"}
{print $10, $12}' file
$ awk 'BEGIN{RS=""; print "AliasName","AliasedObject"} {print $10,$12}' a
AliasName AliasedObject
User1 Administrator,Admin1
User2 Administrator,Admin2
User3 Administrator,Admin3
Upvotes: 3
Reputation: 10039
sed -n '1 i\
AliasName AliasedObject
/^AliasName/ {
s/.*:[[:space:]]*//
N
s/.AliasedObject:[[:space:]]*/ /p
}' YourFile
Upvotes: 2