Вы можете попробовать что-то вроде этого:
apt-get -s upgrade | awk '/^Inst/ {print $2}' |
xargs apt-cache policy |
awk '/:$|^$/ && ! /Version table:/ {print "\n" $0 } ; /:\/\// { print $2 }'
Вывод (только что запущенный на моей системе debian sid) выглядит так:
sqlite3:
http://my.local.mirror.redacted/debian
libsqlite3-0:
http://my.local.mirror.redacted/debian
libsqlite3-0:i386:
http://my.local.mirror.redacted/debian
python-newt:
http://my.local.mirror.redacted/debian
libnewt0.52:
http://my.local.mirror.redacted/debian
libruby:
http://my.local.mirror.redacted/debian
http://my.local.mirror.redacted/debian
mercurial:
http://my.local.mirror.redacted/debian
mercurial-common:
http://my.local.mirror.redacted/debian
http://my.local.mirror.redacted/debian
sysstat:
http://my.local.mirror.redacted/debian
libmilter1.0.1:
http://my.local.mirror.redacted/debian
Некоторые пакеты имеют два URL. Это потому, что моя система - amd64 с i386 в качестве дополнительной архитектуры, и эти пакеты имеют как amd64, так и i386 версии, доступные для обновления.
Если вы предпочитаете иметь полную строку вывода, чтобы она выглядела так:
mercurial-common:
990 http://my.local.mirror.redacted/debian unstable/main amd64 Packages
990 http://my.local.mirror.redacted/debian unstable/main i386 Packages
тогда просто удалите { print $2 }
из второго awk
скрипта.
ls *.DAT | awk -F. '{ if (c[$3$5]) print $0 ; c[$3$5]=$0}'
Выше awk просматривает каждое имя файла, используя .
как разделитель полей. Если до этого он видел комбинацию третьего и пятого полей, он печатает имя файла. С вашими именами файлов в качестве входных данных, приведенное выше дает:
PAT1.URGRSVP.50.WR786842JOB11643.WRS20140.FILE0003.DAT
PAT1.URGRSVP.50.WR786842JOB11694.WRS20140.FILE0002.DAT
БОЛЬШЕ: Давайте рассмотрим команды awk
более подробно:
if (c[$3$5]) print $0 ; c[$3$5]=$0
Вышеупомянутое состоит из двух операторов: одного оператора «if» и одно задание. Оператор «if»:
if (c[$3$5]) print $0
В этом операторе c
является «ассоциативным массивом». Это означает, что вы даете ему ключ, а он возвращает вам значение. Мы используем $ 3 $ 5
в качестве ключа, где $ 3
- третий «блок» (то, что awk называет третьим «полем»), а $ 5
- пятый блокировать. Если этот ключ ранее не был назначен, то c [$ 3 $ 5]
возвращает пустое (ложное) значение. Итак, если эта комбинация третьего и пятого блоков была замечена ранее, то выполняется print $ 0
, что означает, что печатается все имя файла. В противном случае оператор печати пропускается.
Второй оператор:
c[$3$5]=$0
Присваивает имя файла ( $ 0
) ассоциативному массиву под ключом третьего и пятого полей: $ 3 $ 5
.Таким образом, в следующий раз, когда эти поля будут видны в операторе «if», оператор печати будет выполнен.
Вот как это можно сделать с awk
: используйте переменную, чтобы подсчитать, сколько раз вы видели одну и ту же пару из 3-го и 5-го полей, и распечатайте имя файла, если вы уже видели эту конкретную пару.
С этими именами файлов в файле с именем input это будет выглядеть так:
$ awk -F. '{if (dups[$3$5]++) print $0}' input
Если ваши имена файлов могут содержать пробелы или другие забавные символы, используйте find
вместо ls
для вывода списка их можно указать примерно так:
$ find . -name 'PAT1.*.DAT' -print0 | \
awk -F. 'BEGIN{RS="\0"} {if (dups[$3$5]++) print $0}'
В качестве дополнительного преимущества вы можете проверить переменную dups
в блоке END
, чтобы распечатать, сколько пар каждой пары вы видели во входных данных.