Мне разграничили файл с пространством и случайным столбцом, заказывающим следующим образом:
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
К счастью Ваш входной файл имеет формат, оболочка понимает когда дело доходит до присваивающихся переменных значение: 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=...
не работал бы и дал бы синтаксические ошибки. Кроме того, если входной файл содержал бы строку с a bad_command
та команда выполняется потому что именно так eval
работы: это просто выполняет данную строку.
FWIW, вот решение Python как решение для Bash PerlDuck, но не оценка входа.
#!/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
Так как выходной порядок, который Вы хотите, обратный лексический (имя> местоположение> 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