我有一个用空格分隔且列顺序随机的文件,如下所示:
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
答案1
幸运的是,你的输入文件具有 shell 在为变量赋值时可以理解的格式:var1=value1 var2=value2
等等。所以我们可以简单地读取每一行并使用命令eval
来评价線。
将以下内容放入文件中,例如parse.sh
,执行chmod +x parse.sh
并以输入文件作为参数来运行它。
脚本parse.sh
:
#!/usr/bin/env bash
while read line; do
eval $line;
echo "$name|$loc|$ip"
done < "$1"
exit 0;
文件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
跑步:
me@ubuntu:~> ./parse.sh input.txt
Joan|UK|172.20.1.80
Sandra|IR|172.20.1.1
请注意,值中不能有空格。例如
ip=... name=Ubai salih loc=...
无法工作并会出现语法错误。另外,如果输入文件包含带有 的行,则bad_command
该命令将被执行,因为这就是eval
工作原理:它只执行给定的字符串。
答案2
FWIW,这里有一个 Python 解决方案PerlDuck 的 Bash 解决方案,但不评估输入。
#!/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='|')
跑步:
$ ./parse.py input.txt
Joan|UK|172.20.1.80
Sandra|IR|172.20.1.1
答案3
由于您想要的输出顺序是逆向词汇顺序 (name > loc > ip),因此您可以选择字段,然后对其进行逆向排序,然后删除前缀fieldname=
。例如在 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