В этом случае было бы намного проще и (намного быстрее) использовать awk
. awk
предоставляет массивы и гораздо более способен обрабатывать входные записи, чем read
. С awk
вы просто пишете правила, которые будут применяться к каждой строке ввода. В вашем случае вам просто нужно определить, начинается ли строка с "DN:"
, "Serial:"
или "Serialized"
. Затем вы можете сохранить связанное значение в отдельном массиве, скажем, массивах dn
, serial
и serid
. Чтобы выполнить это в awk
, вам ничего не нужно:
awk '
$1 == "Certificate" {n++}; # increment n
NF == 2 { # fill dn & serial array
$1 == "DN:" && dn[n]=$2
$1 == "Serial:" && serial[n]=$2
}
NF == 3 { # fill serid array
$1 == "Serialized" && serid[n]=$3
}
END { # output results
print "\nDN:\t\tSerial:\t\tSerialized id:"
for (i in dn) print dn[i], "\t\t", serial[i], "\t\t", serid[i]
}' file
Выше, если первое поле ($1
) равно "Certificate"
, вы просто увеличиваете счетчик. Если в строке 2 поля (NF == 2
), то вы проверяете, начинается ли строка с "DN:"
или "Serial"
и добавляете 2-е поле в соответствующий массив. Если в строке 3 поля ("Serialized", "id:"
и ваше значение), вы сохраняете значение в массиве serid
.
Со всеми сохраненными значениями вы можете перебирать массивы в правиле END
,предоставляя любой вывод, который вам нужен. Над ним просто выводится контент в табличной форме. Вы можете просто скопировать / усечь вставку средней кнопкой мыши в командной строке для проверки.
Пример Использование / Вывод
$ awk '
> $1 == "Certificate" {n++}; # increment n
> NF == 2 { # fill dn & serial array
> $1 == "DN:" && dn[n]=$2
> $1 == "Serial:" && serial[n]=$2
> }
> NF == 3 { # fill serid array
> $1 == "Serialized" && serid[n]=$3
> }
> END { # output results
> print "\nDN:\t\tSerial:\t\tSerialized id:"
> for (i in dn) print dn[i], "\t\t", serial[i], "\t\t", serid[i]
> }' file
DN: Serial: Serialized id:
XXX XXXX XXXX
XXXX XXXX XXXX
XXXXX XXXX XXXX
Для обработки больших файлов, awk
будет на порядка быстрее, чем цикл в сценарии оболочки. Дайте мне знать, удовлетворяет ли это вашим потребностям, если вам нужна дополнительная помощь.
Редактировать за комментарий
Если вы имеете дело с файлом, в котором есть смешанные табуляции и пробелыПри использовании разделителей это может вызвать проблемы при разборе awk
с использованием стандартного разделителя полей (пробел). Чтобы рассматривать последовательность смешанных пробелов / табуляций как разделитель, в GNU awk
вы можете указать регулярное выражение для разделителя. Например, учитывая последовательность из одного или нескольких пробелов или табуляций, можно указать как -F'[ \t]+'
. В приведенном ниже примере используется разделитель. (примечание: в результате номера полей изменятся)
awk -F'[ \t]+' '
$1 == "Certificate" {n++}; # increment n
NF == 3 { # fill dn & serial array
$2 == "DN:" && dn[n]=$3
$2 == "Serial:" && serial[n]=$3
}
NF == 4 { # fill serid array
$2 == "Serialized" && serid[n]=$4
}
END { # output results
print "\nDN:\t\tSerial:\t\tSerialized id:"
for (i in dn) print dn[i], "\t\t", serial[i], "\t\t", serid[i]
}' f
Пример использования / Вывод
С такими же данными вы получите:
$ awk -F'[ \t]+' '
> $1 == "Certificate" {n++}; # increment n
> NF == 3 { # fill dn & serial array
> $2 == "DN:" && dn[n]=$3
> $2 == "Serial:" && serial[n]=$3
> }
> NF == 4 { # fill serid array
> $2 == "Serialized" && serid[n]=$4
> }
> END { # output results
> print "\nDN:\t\tSerial:\t\tSerialized id:"
> for (i in dn) print dn[i], "\t\t", serial[i], "\t\t", serid[i]
> }' f
DN: Serial: Serialized id:
XXX XXXX XXXX
XXXX XXXX XXXX
XXXXX XXXX XXXX
Не зная, какова структура пробела / табуляции вашего опубликованного текста, это должно учитывать любой случай.
Дальнейшее обновление Публикация входных данных, взятых из вопроса
Ниже приведен входной файл f
(или file
), используемый с примерами выше. Это было взято из вашего вопроса, но нет никакой гарантии, что перевод пробела / табуляции будет таким же, как в вопросе. Последний пример выше должен справиться с этим независимо. Единственное другое предостережение: если у вас есть файл с окончанием строки DOS, который вы вводите в awk
- он не будет работать. Вы можете проверить, запустив утилиту file yourfilename
, и она сообщит, что в DOS CRLF
имеются окончания строки. Затем вы можете использовать dos2unix yourfilename
, чтобы исправить проблему и преобразовать файл в окончания строк Unix / POSIX.
Пример входного файла
$ cat f
The following objects are available for use.
Each object shown below may be used as parameter to
--pkcs11-id option please remember to use single quote mark.
Certificate
DN: XXX
Serial: XXXX
Serialized id: XXXX
Certificate
DN: XXXX
Serial: XXXX
Serialized id: XXXX
Certificate
DN: XXXXX
Serial: XXXX
Serialized id: XXXX
Hexdump
$ hexdump -Cv f
00000000 54 68 65 20 66 6f 6c 6c 6f 77 69 6e 67 20 6f 62 |The following ob|
00000010 6a 65 63 74 73 20 61 72 65 20 61 76 61 69 6c 61 |jects are availa|
00000020 62 6c 65 20 66 6f 72 20 75 73 65 2e 0a 45 61 63 |ble for use..Eac|
00000030 68 20 6f 62 6a 65 63 74 20 73 68 6f 77 6e 20 62 |h object shown b|
00000040 65 6c 6f 77 20 6d 61 79 20 62 65 20 75 73 65 64 |elow may be used|
00000050 20 61 73 20 70 61 72 61 6d 65 74 65 72 20 74 6f | as parameter to|
00000060 0a 2d 2d 70 6b 63 73 31 31 2d 69 64 20 6f 70 74 |.--pkcs11-id opt|
00000070 69 6f 6e 20 70 6c 65 61 73 65 20 72 65 6d 65 6d |ion please remem|
00000080 62 65 72 20 74 6f 20 75 73 65 20 73 69 6e 67 6c |ber to use singl|
00000090 65 20 71 75 6f 74 65 20 6d 61 72 6b 2e 0a 0a 43 |e quote mark...C|
000000a0 65 72 74 69 66 69 63 61 74 65 0a 20 20 20 20 20 |ertificate. |
000000b0 20 20 44 4e 3a 20 20 20 20 20 20 20 20 20 20 20 | DN: |
000000c0 20 20 58 58 58 0a 20 20 20 20 20 20 20 53 65 72 | XXX. Ser|
000000d0 69 61 6c 3a 20 20 20 20 20 20 20 20 20 58 58 58 |ial: XXX|
000000e0 58 0a 20 20 20 20 20 20 20 53 65 72 69 61 6c 69 |X. Seriali|
000000f0 7a 65 64 20 69 64 3a 20 20 58 58 58 58 0a 0a 43 |zed id: XXXX..C|
00000100 65 72 74 69 66 69 63 61 74 65 0a 20 20 20 20 20 |ertificate. |
00000110 20 20 44 4e 3a 20 20 20 20 20 20 20 20 20 20 20 | DN: |
00000120 20 20 58 58 58 58 0a 20 20 20 20 20 20 20 53 65 | XXXX. Se|
00000130 72 69 61 6c 3a 20 20 20 20 20 20 20 20 20 58 58 |rial: XX|
00000140 58 58 0a 20 20 20 20 20 20 20 53 65 72 69 61 6c |XX. Serial|
00000150 69 7a 65 64 20 69 64 3a 20 20 58 58 58 58 0a 0a |ized id: XXXX..|
00000160 43 65 72 74 69 66 69 63 61 74 65 0a 20 20 20 20 |Certificate. |
00000170 20 20 20 44 4e 3a 20 20 20 20 20 20 20 20 20 20 | DN: |
00000180 20 20 20 58 58 58 58 58 0a 20 20 20 20 20 20 20 | XXXXX. |
00000190 53 65 72 69 61 6c 3a 20 20 20 20 20 20 20 20 20 |Serial: |
000001a0 58 58 58 58 0a 20 20 20 20 20 20 20 53 65 72 69 |XXXX. Seri|
000001b0 61 6c 69 7a 65 64 20 69 64 3a 20 20 58 58 58 58 |alized id: XXXX|
000001c0 0a |.|
000001c1
Дайте мне знать результаты вашего рассмотрения файла.