Мне сделали текстовый файл из вывода инструмента управления репозитория aptly
, который перечисляет мои опубликованные репозитории, из которых я должен извлечь информацию.
Формат файла следующие:
Published repositories:
* test_repo_one/xenial [i386,amd64] publishes {main: [xenial-main_20190311]: Snapshot from mirror [xenial-main]: http//gb.archive.ubuntu.com/ubuntu/ xenial [src]}, {multiverse: [xenial-multiverse_20190311]: Snapshot from mirror [xenial-multiverse]: http//gb.archive.ubuntu.com/ubuntu/ xenial [src]}, {restricted: [xenial-restricted_20190311]: Snapshot from mirror [xenial-restricted]: http//gb.archive.ubuntu.com/ubuntu/ xenial [src]}, {universe: [xenial-universe_20190311]: Snapshot from mirror [xenial-universe]: http//gb.archive.ubuntu.com/ubuntu/ xenial [src]}
* test_repo_one/xenial-security [i386,amd64] publishes {main: [xenial-security-main_20190311]: Snapshot from mirror [xenial-security-main]: http//gb.archive.ubuntu.com/ubuntu/ xenial-security[src]}, {multiverse: [xenial-security-multiverse_20190311]: Snapshot from mirror [xenial-security-multiverse]: http//gb.archive.ubuntu.com/ubuntu/ xenial-security[src]}, {restricted: [xenial-security-restricted_20190311]: Snapshot from mirror [xenial-security-restricted]: http//gb.archive.ubuntu.com/ubuntu/ xenial-security[src]}, {universe: [xenial-security-universe_20190311]: Snapshot from mirror [xenial-security-universe]: http//gb.archive.ubuntu.com/ubuntu/ xenial-security[src]}
* test_repo_two/trusty [i386,amd64] publishes {main: [trusty-main_20190312]: Snapshot from mirror [trusty-main]: http//gb.archive.ubuntu.com/ubuntu/ trusty[src]}, {multiverse: [trusty-multiverse_20190312]: Snapshot from mirror [trusty-multiverse]: http//gb.archive.ubuntu.com/ubuntu/ trusty[src]}, {restricted: [trusty-restricted_20190312]: Snapshot from mirror [trusty-restricted]: http//gb.archive.ubuntu.com/ubuntu/ trusty[src]}, {universe: [trusty-universe_20190312]: Snapshot from mirror [trusty-universe]: http//gb.archive.ubuntu.com/ubuntu/ trusty[src]}
...
Последняя строка вывода заканчивается в новой строке.
"Опубликованные репозитории": строка не требуется.
Для каждого запуска строк '*' я должен удалить постороннюю информацию, уезжать только создает снимки имена. Нет никакого способа выполнить в этом aptly
. Желаемый вывод для первой из этих строк.
test_repo_one/xenial [xenial-main_20190311] [xenial-multiverse_20190311] [xenial-restricted_20190311] [xenial-universe_20190311]
Квадратные скобки не важны или так решение, которое сохраняет или удаляет, они прекрасны. Я предпочел бы a sed
или awk
решение, но что-либо, что работает, высоко ценилось бы.
Подход Perl:
$ perl -lne 'next unless /^\s*\*\s*(\S+)/; $n=$1; @k=(/\{.+?:\s*\[(.+?)\]/g); print "$n @k"' file
test_repo_one/xenial xenial-main_20190311 xenial-multiverse_20190311 xenial-restricted_20190311 xenial-universe_20190311
test_repo_one/xenial-security xenial-security-main_20190311 xenial-security-multiverse_20190311 xenial-security-restricted_20190311 xenial-security-universe_20190311
test_repo_two/trusty trusty-main_20190312 trusty-multiverse_20190312 trusty-restricted_20190312 trusty-universe_20190312
perl -lne
: считайте входной файл линию за линией (-n
), удалите запаздывание новых строк (-l
) и запущенный скрипт, данный -e
на каждой строке. -l
также добавляет новую строку к каждому print
звонить. next unless /^\s*\*\s*(\S+)/;
: найдите название repo, таким образом, первый фрагмент непробельных символов (\S+
) на строке, которая запускается с 0 или больше пробельных символов (^\s*
), затем a *
(\*
), и 0 или больше пробельных символов снова. Самый длинный фрагмент непробела после этого - то, что мы хотим. Если эта строка не соответствует этому regex, next
перейдет нас на следующую строку.$n=$1
: сохраните то, что было получено соответствием выше ( (\S+)
в круглых скобках, $1
) как $n
. @k=(/\{.+?:\s*\[(.+?)\]/g)
: найдите все случаи, где у нас есть a {
, любые другие символы и затем a :
, сопровождаемый пробелом и a [
и получите что-либо между [
и ]
. Сохраните все соответствующие строки в массиве @k
. print "$n @k"
: наконец, распечатайте название repo, $n
, и массив @k
сверху. Если Вы предпочитаете включать квадратные скобки, можно использовать:
$ perl -lne 'next unless /^\s*\*\s*(\S+)/; $n=$1; @k=(/\{.+?:\s*(\[.+?\])/g); print "$n @k"' file
test_repo_one/xenial [xenial-main_20190311] [xenial-multiverse_20190311] [xenial-restricted_20190311] [xenial-universe_20190311]
test_repo_one/xenial-security [xenial-security-main_20190311] [xenial-security-multiverse_20190311] [xenial-security-restricted_20190311] [xenial-security-universe_20190311]
test_repo_two/trusty [trusty-main_20190312] [trusty-multiverse_20190312] [trusty-restricted_20190312] [trusty-universe_20190312]
Я отправил два ответа здесь:
grep
, sed
и cut
Я выключил терминальную гномом строку, переносятся для создания входных и выходных файлов легче читать.
───────────────────────────────────────────────────────────────────────────────────────────
rick@alien:~/askubuntu$ tput rmam # Turn off line wrap
───────────────────────────────────────────────────────────────────────────────────────────
rick@alien:~/askubuntu$ cat aptfilein
Published repositories:
* test_repo_one/xenial [i386,amd64] publishes {main: [xenial-main_20190311]: Snapshot from mirr}
* test_repo_one/xenial-security [i386,amd64] publishes {main: [xenial-security-main_20190311]: }
* test_repo_two/trusty [i386,amd64] publishes {main: [trusty-main_20190312]: Snapshot from mirr}
...
───────────────────────────────────────────────────────────────────────────────────────────
rick@alien:~/askubuntu$ time aptfileparse.sh
5 lines read from aptfilein
3 lines written to aptfileout
real 0m0.025s
user 0m0.016s
sys 0m0.004s
───────────────────────────────────────────────────────────────────────────────────────────
rick@alien:~/askubuntu$ cat aptfileout
test_repo_one/xenial [xenial-main_20190311] [xenial-multiverse_20190311] [xenial-restricted_201]
test_repo_one/xenial-security [xenial-security-main_20190311] [xenial-security-multiverse_20190]
test_repo_two/trusty [trusty-main_20190312] [trusty-multiverse_20190312] [trusty-restricted_201]
───────────────────────────────────────────────────────────────────────────────────────────
rick@alien:~/askubuntu$
Не забудьте делать исполняемый файл сценария с chmod a+x script.sh
#!/bin/bash
# NAME: aptfileparse.sh
# PATH: ~/askubuntu
# DESC: Parse Apt File giving new lines.
# DATE: July 1, 2019.
# NOTE: For: https://askubuntu.com/questions/1127821/text-processing-aptly-output-file
# Program would be ~10 lines shorter (but harder to read) with arrays.
: <<'END'
/* -----------------------------------------------------------------------------
INPUT FILE LAYOUT
=================
Published repositories:
* test_repo_one/xenial [i386,amd64] publishes {main: [xenial-main_20190311]: Snapshot from mirror [xenial-main]: http//gb.archive.ubuntu.com/ubuntu/ xenial [src]}, {multiverse: [xenial-multiverse_20190311]: Snapshot from mirror [xenial-multiverse]: http//gb.archive.ubuntu.com/ubuntu/ xenial [src]}, {restricted: [xenial-restricted_20190311]: Snapshot from mirror [xenial-restricted]: http//gb.archive.ubuntu.com/ubuntu/ xenial [src]}, {universe: [xenial-universe_20190311]: Snapshot from mirror [xenial-universe]: http//gb.archive.ubuntu.com/ubuntu/ xenial [src]}
* test_repo_one/xenial-security [i386,amd64] publishes {main: [xenial-security-main_20190311]: Snapshot from mirror [xenial-security-main]: http//gb.archive.ubuntu.com/ubuntu/ xenial-security[src]}, {multiverse: [xenial-security-multiverse_20190311]: Snapshot from mirror [xenial-security-multiverse]: http//gb.archive.ubuntu.com/ubuntu/ xenial-security[src]}, {restricted: [xenial-security-restricted_20190311]: Snapshot from mirror [xenial-security-restricted]: http//gb.archive.ubuntu.com/ubuntu/ xenial-security[src]}, {universe: [xenial-security-universe_20190311]: Snapshot from mirror [xenial-security-universe]: http//gb.archive.ubuntu.com/ubuntu/ xenial-security[src]}
* test_repo_two/trusty [i386,amd64] publishes {main: [trusty-main_20190312]: Snapshot from mirror [trusty-main]: http//gb.archive.ubuntu.com/ubuntu/ trusty[src]}, {multiverse: [trusty-multiverse_20190312]: Snapshot from mirror [trusty-multiverse]: http//gb.archive.ubuntu.com/ubuntu/ trusty[src]}, {restricted: [trusty-restricted_20190312]: Snapshot from mirror [trusty-restricted]: http//gb.archive.ubuntu.com/ubuntu/ trusty[src]}, {universe: [trusty-universe_20190312]: Snapshot from mirror [trusty-universe]: http//gb.archive.ubuntu.com/ubuntu/ trusty[src]}
...
OUTPUT FILE LAYOUT
==================
test_repo_one/xenial [xenial-main_20190311] [xenial-multiverse_20190311] [xenial-restricted_20190311] [xenial-universe_20190311]
Five fields to extract: name, main, multiverse, restricted, universe
----------------------------------------------------------------------------- */
END
INPUT="aptfilein"
OUTPUT="aptfileout"
> "$OUTPUT" # Erase previous output file
# Read all input lines
while IFS= read -r line ; do
let CountIn++
! [[ "$line" =~ " *" ]] && continue # skip lines not starting " *"
# Get name
line="${line#" * "}" # remove leading " * "
lout="${line%%" "*}" # name is up to next " "
line="${line#" "*}" # remove name from line
# Get main
line="${line#*"{main: "}" # remove leading "{main: "
lout="$lout ${line%%":"*}" # main is up to next ":"
line="${line#":"*}" # remove name from line
# Get multiverse
line="${line#*"{multiverse: "}" # remove leading "{multiverse: "
lout="$lout ${line%%":"*}" # maultiverse is up to next ":"
line="${line#":"*}" # remove multiverse from line
# Get restricted
line="${line#*"{restricted: "}" # remove leading "{restricted: "
lout="$lout ${line%%":"*}" # restricted is up to next ":"
line="${line#":"*}" # remove restricted from line
# Get universe
line="${line#*"{universe: "}" # remove leading "{universe: "
lout="$lout ${line%%":"*}" # universe is up to next ":"
line="${line#":"*}" # remove universe from line
# Append line to output file with leading space
echo " $lout" >> "$OUTPUT"
let CountOut++
done < "$INPUT"
echo "$CountIn lines read from $INPUT"
echo "$CountOut lines written to $OUTPUT"
Остроты популярны в сообществе Linux и существуют некоторые превосходные awk
и perl
ответы отправляются в этом Вопросы и ответы. Вот пример с помощью общих утилит, с которыми большинство опытных пользователей командной строки знакомо:
$ time grep ^" \*" aptfilein | sed 's/ \* //;s/ /: /;s/^/ /' | cut -d':' -f1,3,6,9,12 --output-delimiter=''
test_repo_one/xenial [xenial-main_20190311] [xenial-multiverse_20190311] [xenial-restricted_20190311] [xenial-universe_20190311]
test_repo_one/xenial-security [xenial-security-main_20190311] [xenial-security-multiverse_20190311] [xenial-security-restricted_20190311] [xenial-security-universe_20190311]
test_repo_two/trusty [trusty-main_20190312] [trusty-multiverse_20190312] [trusty-restricted_20190312] [trusty-universe_20190312]
real 0m0.011s
user 0m0.003s
sys 0m0.008s
grep ^" \*" aptfilein
- grep
команда выбирает строки, содержащие строку поиска. Морковь (^
) обозначает, что строка должна запуститься в начале строки. Обратная косая черта (\
) обозначает звездочку/нащельную рейку (*
) должен быть взят буквально и не действие как подстановочный символ, который выбирает все. Таким образом, это grep
команда выбирает все начало строк *
в файле aptfilein
.sed
"потоковый редактор", который редактирует входящие строки и изменяет их и раздает их. Существуют три sed
изменения здесь 's/ \* //;s/ /: /;s/^/ /'
. Изменения между кавычками ('
) и очерченный (разделенный) точкой с запятой (;
) deliminator. Они сломаны на следующие три точки.s/ \* //
- поисковое первое вхождение *
и измените его на пустой указатель. Это сотрется *
это начинается в каждой строке.s/ /: /
- поиски первого пространства и изменений это в двоеточие (:
) сопровождаемый пространством. Это необходимо для изменения нашего первого поля в ключ. Например, test_repo_one/xenial
становится test_repo_one/xenial:
.s/^/ /
- говорит sed
вставлять пробел в начале каждой строки.cut -d':' -f1,3,6,9,12 --output-delimiter=''
- Использование cut
управляйте для выбора полей ключа № 1, 3, 6, 9 и 12. Поля ключа разграничены двоеточием как аргумент -d':'
предусматривает. Обычно выходные поля разграничены то же, но это переопределяется к использованию пустого указателя - выходной разделитель ='' параметр.Примечание: Острота быстрее, чем удар, который медленнее при строковой обработке.
Мой подход awk:
$ cat 1.txt
Published repositories:
* test_repo_one/xenial [i386,amd64] publishes {main: [xenial-main_20190311]: Snapshot from mirror [xenial-main]: http//gb.archive.ubuntu.com/ubuntu/ xenial [src]}, {multiverse: [xenial-multiverse_20190311]: Snapshot from mirror [xenial-multiverse]: http//gb.archive.ubuntu.com/ubuntu/ xenial [src]}, {restricted: [xenial-restricted_20190311]: Snapshot from mirror [xenial-restricted]: http//gb.archive.ubuntu.com/ubuntu/ xenial [src]}, {universe: [xenial-universe_20190311]: Snapshot from mirror [xenial-universe]: http//gb.archive.ubuntu.com/ubuntu/ xenial [src]}
* test_repo_one/xenial-security [i386,amd64] publishes {main: [xenial-security-main_20190311]: Snapshot from mirror [xenial-security-main]: http//gb.archive.ubuntu.com/ubuntu/ xenial-security[src]}, {multiverse: [xenial-security-multiverse_20190311]: Snapshot from mirror [xenial-security-multiverse]: http//gb.archive.ubuntu.com/ubuntu/ xenial-security[src]}, {restricted: [xenial-security-restricted_20190311]: Snapshot from mirror [xenial-security-restricted]: http//gb.archive.ubuntu.com/ubuntu/ xenial-security[src]}, {universe: [xenial-security-universe_20190311]: Snapshot from mirror [xenial-security-universe]: http//gb.archive.ubuntu.com/ubuntu/ xenial-security[src]}
* test_repo_two/trusty [i386,amd64] publishes {main: [trusty-main_20190312]: Snapshot from mirror [trusty-main]: http//gb.archive.ubuntu.com/ubuntu/ trusty[src]}, {multiverse: [trusty-multiverse_20190312]: Snapshot from mirror [trusty-multiverse]: http//gb.archive.ubuntu.com/ubuntu/ trusty[src]}, {restricted: [trusty-restricted_20190312]: Snapshot from mirror [trusty-restricted]: http//gb.archive.ubuntu.com/ubuntu/ trusty[src]}, {universe: [trusty-universe_20190312]: Snapshot from mirror [trusty-universe]: http//gb.archive.ubuntu.com/ubuntu/ trusty[src]}
$ awk '$1=="*"{split ($0, a, /:/); print $2 a[2] a[5] a[8] a[11]}' 1.txt
test_repo_one/xenial [xenial-main_20190311] [xenial-multiverse_20190311] [xenial-restricted_20190311] [xenial-universe_20190311]
test_repo_one/xenial-security [xenial-security-main_20190311] [xenial-security-multiverse_20190311] [xenial-security-restricted_20190311] [xenial-security-universe_20190311]
test_repo_two/trusty [trusty-main_20190312] [trusty-multiverse_20190312] [trusty-restricted_20190312] [trusty-universe_20190312]