我有一個用空格和隨機列順序定界的文件,如下所示:
name=Joan age=42 ip=172.20.1.80 sex=M loc=UK
loc=IR sex=F ip=172.20.1.1 age=32 name=Sandra
我只想提取特定字段(name
,loc
和ip
)。
所以我要尋找的結果如下:
Joan|UK|172.20.1.80
Sandra|IR|172.20.1.1
我有一個用空格和隨機列順序定界的文件,如下所示:
name=Joan age=42 ip=172.20.1.80 sex=M loc=UK
loc=IR sex=F ip=172.20.1.1 age=32 name=Sandra
我只想提取特定字段(name
,loc
和ip
)。
所以我要尋找的結果如下:
Joan|UK|172.20.1.80
Sandra|IR|172.20.1.1
Luckily, your input file has a format the shell understands when it comes to
assigning variables a value: var1=value1 var2=value2
etc. So we can simply
read each line and use the eval
command to evaluate the line.
Put the following into a file, say parse.sh
, do chmod +x parse.sh
and
run it with your input file as a parameter.
Script parse.sh
:
#!/usr/bin/env bash
while read line; do
eval $line;
echo "$name|$loc|$ip"
done < "$1"
exit 0;
File input.txt
:
name=Joan age=42 ip=172.20.1.80 sex=M loc=UK
loc=IR sex=F ip=172.20.1.1 age=32 name=Sandra
Run:
[email protected]:~> ./parse.sh input.txt
Joan|UK|172.20.1.80
Sandra|IR|172.20.1.1
Please note that the values must not have a space in them. E.g.
ip=... name=Ubai salih loc=...
would not work and give syntax errors. Also, if the input file would contain a line with a bad_command
that command gets executed because that is how eval
works: it just executes the given string.
Since the output order that you want is reverse lexical (name > loc > ip) you could select and then reverse sort the fields, then remove the fieldname=
prefixes. For example in Perl:
$ perl -alne '
print join "|", map { s/.*=//r } reverse sort grep { /^(name|loc|ip)=/ } @F
' file
Joan|UK|172.20.1.80
Sandra|IR|172.20.1.1
FWIW, here's a Python solution like PerlDuck's Bash solution, but not evaluating the input.
#!/usr/bin/env python3
import fileinput
for line in fileinput.input():
record = line.rstrip('\n')
d = dict(kv.split('=') for kv in record.split(' '))
print(d['name'], d['loc'], d['ip'], sep='|')
Run:
$ ./parse.py input.txt
Joan|UK|172.20.1.80
Sandra|IR|172.20.1.1