вывод grep из длинного в широкий

Наконец-то устранена проблема. $LIBпеременная среды расширяется до каталога lib32для 32 -битных программ и lib/x86_64-linux-gnuдля 64 -битных программ (как /usr/$LIB/mysharedlibrary.soв /etc/ld.so.preload)-, как показано в strace. Это для систем на основе Debian, так как для других систем он будет расширяться до lib64, аlib(всегда может подтверждаться strace, в частности системным вызовом openat()).

Таким образом, решение состоит в том, чтобы скомпилировать общую библиотеку с -m32и -m64и поместить соответствующие файлы архитектуры в соответствующие папки из $LIB.

Резюме (пример):

$ mkdir {32,64}
$ gcc -Wall -m32 -fPIC -shared -o 32/mysharedlibrary.so mysharedlibrary.c -ldl
$ gcc -Wall -fPIC -shared -o 64/mysharedlibrary.so mysharedlibrary.c -ldl
$ sudo mv 32/mysharedlibrary.so /usr/lib32/mysharedlibrary.so
$ sudo mv 64/mysharedlibrary.so /usr/lib/x86_64-linux-gnu/mysharedlibrary.so
$ sudo echo '/usr/$LIB/mysharedlibrary.so' > /etc/ld.so.preload
6
14.02.2021, 19:03
4 ответа

Использование GNUdatamash:

$ grep -n -x -F -f fileA.txt fileB.txt | datamash -s -t : -g 2 collapse 1
Germany:4,9
UK:5,6
USA:1,2,11

Сначала используется grepдля получения строк из fileB.txt, которые точно соответствуют строкам в fileA.txt, и выводятся совпадающие номера строк вместе с самими строками.

Я использую -xи -Fв дополнение к параметрам, которые используются в вопросе. Я делаю это, чтобы не читать шаблоны из fileA.txtкак регулярные выражения(-F)и сопоставлять полные строки, а не подстроки(-x).

Утилита datamashзатем анализирует это как строки:-полей с разделителями (-t :), сортируя их(-s)по второму полю(-g 2; страны )и схлопывание первого поля(collapse 1; номера строк )в список для каждой страны.

Очевидно, вы могли бы заменить двоеточия и запятые табуляцией, используя tr ':,' '\t\t', или пробелами аналогичным образом.

$ grep -n -x -f fileA.txt -F fileB.txt | datamash -s -t : -g 2 collapse 1 | tr ':,' '\t\t'
Germany 4       9
UK      5       6
USA     1       2       11
11
18.03.2021, 22:30

Используйтеawk:

awk 'NR==FNR        { country[$0]= country[$0]? country[$0] FS NR: NR; next }
     ($0 in country){ print $0, country[$0] }' fileB fileA

или сообщить «count:0 » в случае, если в файле A есть имя страны, которого нет в файле B, выполните:

awk 'NR==FNR        { country[$0]= country[$0]? country[$0] FS NR: NR; next }
     ($0 in country){ print $0, country[$0]; next } { print $0, "0" }' fileB fileA
8
18.03.2021, 22:30
$ grep -nxFf fileA.txt you fileB.txt   \
| awk -F: '$0 = (length($2) FS $0)' \
| sort -t: -k1,1nr -k3,3 -k2,2n \
| cut -d: -f2- \
| sed -Ee '
  :a
    $!N;y/:/ /
    s/( \S+)\n(.*\1)$/ \2/
  ta
  s/([^\n]*) ([^\n]*)((\n.*)?)$/\2 \1\3/
  P;D
'

О/П:

Germany 4 9
USA 1 2 11
UK 5 6

Обратите внимание, :для этого требуется, чтобы GNU sed мог работать, так как используются \S и \n в классах char.

2
18.03.2021, 22:30

Вы можете соединить выходные данные команды grep с Миллером(https://github.com/johnkerl/miller)и запустить

grep -nf fileA.txt fileB.txt | \
mlr --c2n --ifs ":" --implicit-csv-header --headerless-csv-output reorder -f 2  then \
nest --implode --values --across-records --nested-fs " " -f 1

У вас будет

Germany 4 9
USA 1 2 11
UK 5 6
5
18.03.2021, 22:30

Теги

Похожие вопросы