Это не совсем то, о чем вы просили, но это может сработать для ваших нужд. Вы можете сериализовать данные с помощью Awk. Обратите внимание, что это не работает, если ваш $ 1 не является допустимым именем переменной:
awk '
function quote(str, d, m, x, y, z) {
d = "\47"; m = split(str, x, d)
for (y in x) z = z d x[y] (y < m ? d "\\" d : d)
return z
}
{
print $1 "=" quote($0)
}
' input.txt > /tmp/input.sh
. /tmp/input.sh
Результат:
$ echo "$line1"
line1 foo foobar bar
Если у вас GNU awk
> 4.0 и предполагается, что запись Order
всегда предшествует записи Package
, тогда
gawk '/^Order/ {order = $2} /^Package/ {p[order] = $0}
END {
PROCINFO["sorted_in"] = "@ind_num_asc"
for (i in p) {print "Order:", i; print p[i]}
}
' conf/*.conf
Order: 0
Package: example
Order: 1
Package: file
Order: 2
Package: another
Для более старых gawk
вы можете использоватьasorti
:
gawk '/^Order/ {order = $2} /^Package/ {p[order] = $0}
END {
n = asorti(p,b)
for (i=1;i<=n;i++) {print "Order:", i; print p[b[i]]}
}
' conf/*.conf
Работает только для файлов, содержащих две строки.
sed -n 'N; s/\n//p' *.conf | sort | sed -n 's/\(Package\)/\n\1/p'
Пояснение:
sed -n 'N; s/\n//p' *.conf
-удаляет новую строку между двумя строками, то есть соединяет две смежные строки в одну. sort
-сортирует длинные строки, что было сделано на предыдущем шаге. sed -n 's/\(Package\)/\n\1/p'
-возвращает новую строку на место. Выход:
Order: 0
Package: example
Order: 1
Package: file
Order: 2
Package: another
Наивный подход Unix:
awk '/Order|Package/' conf/*.conf | # get your usual output
paste - - | # convert two lines to one
sort -n -k2,2 | # sort numerically
awk '{print $1,$2;print $3,$4}' # re-print in two columns
#!/usr/bin/env python
from __future__ import print_function
import sys
def get_order_package(filename):
order=None
package=None
with open(filename) as f:
for line in f:
if line.startswith('Order:'):
order=int(line.strip().split()[1])
if line.startswith('Package:'):
package=line.strip().replace("Package: ",'')
return (order,package)
order_list=[]
for argument in sys.argv[1:]:
order_list.append(get_order_package(argument))
order_list.sort(key=lambda x: x[0])
for i in order_list:
print('Order:',i[0])
print('Package:',i[1])
Этот скрипт определяет get_order_package()
функцию, которая анализирует файл и возвращает кортеж в формате (integer,package_string)
. Мы передаем все файлы в качестве аргументов строки команды -и перебираем их, выполняя описанную выше функцию для каждого из них. Это создает список, мы сортируем его и повторяем снова, печатая каждую соответствующую часть кортежа из нового отсортированного списка.
$ cat example_1.conf
Order: 0
Package: example_1
$ cat example_2.conf
Order: 2
Package: example_2
$ cat example_3.conf
Order: 1
Package: example_3
$./parse_conf.py *.conf
Order: 0
Package: example_1
Order: 1
Package: example_3
Order: 2
Package: example_2
Это тоже работает:
grep -e ^Order -e ^Package `grep ^Order *.conf | awk -F: '{printf("%s:%s\n",$NF,$0);}' |sort| awk -F: '{print $2}'`
Объяснение (ниже многострочного формата -предназначено только для демонстрации, не работает в bash, поскольку результирующая однострочная команда -не может обрабатывать комментарии ):
$ grep -e ^Order -e ^Package ` \ # grep for lines starting with "Order" or "Package"; start nested command
> grep ^Order *.conf | \ # grep for lines starting with "Order" in files *.conf
> awk -F: '{printf("%s:%s\n",$NF,$0);}' | \ # prefixing order number with a separating colon
> sort | \ # sort by order number
> awk -F: '{print $2}' \ # extract file name alone ; now filenames are ordered by the order number contained within them
> ` # end nested command