Perl-скрипт для удаления строки из одного файла, разделенного вертикальной чертой, с использованием другого файла, имеющего один соответствующий столбец

Предполагается, что Linux (не FreeBSD ... ).

Это должно отключить специальные функции Alt+Left или Alt+Right, оставив только клавиши Alt+Fn для смены консоли. Его следует запускать на консоли, и для загрузки новой раскладки требуется root :

.

dumpkeys > backup-keymap
dumpkeys | sed 's/Decr_Console/Left/g;s/Incr_Console/Right/g' | loadkeys

Для возврата используйте loadkeys < backup-keymapили перезапустите какой-либо инструмент настройки системной клавиатуры.

Я не знаю, как правильно интегрировать это при загрузке в раскладку клавиатуры. Это может зависеть от дистрибутива (и при использовании systemd...)

Файл/etc/console-setup/remap.incв Debian может дать больше подсказок о том, как правильно переопределить клавиатуру вместо этих низкоуровневых команд в Debian.

-2
24.01.2020, 10:57
1 ответ

Предполагая, что порядок результата не важен:

$ join -v 1 -t '|' -1 2 <( sort -t '|' -k2,2 fileA ) <( sort fileB )
777504559|2020-01-19|2|15|1|403941|53|4708267|3036|5033|127380343|0|3905585|C|1168|IRU|107|NR
847082255|2020-01-19|2|15|1|2|2|284|3036|291|125650195|125650195|8870299|C|1168|IRU|1|NR
858760375|2020-01-19|2|15|1|2|2|117|3036|109|2739523|5208959|4037061|C|1168|IRU|2|NR
858760375|2020-01-19|2|15|1|403941|53|4708267|3036|306|99931425|0|8866849|C|1168|IRU|107|NR
869323039|2020-01-19|2|15|1|2|2|371|3036|307|106104029|106104029|4518435|C|1168|IRU|2|NR
872268371|2020-01-19|2|15|1|403941|53|4708267|3036|143|127382679|0|8866849|C|1168|IRU|107|NR

Утилита joinвыполняет реляционную операцию INNER JOIN для двух заданных наборов данных. Наборы данных должны быть отсортированы по столбцам, к которым мы присоединяемся, поэтому мы сортируем файлы перед вызовом join(, если ваша оболочка не поддерживает замены процессов, предварительно -сортируем файлы отдельно ). Параметры, которые мы используем с joinздесь, -t '|'и -1 2, означают «использовать |в качестве разделителя столбца и соединить второй столбец первого набора данных» (, в противном случае первый столбец является по умолчанию ).

С помощью -v 1мы запрашиваем все строки из первого файла, которые не могут быть соединены со строками из второго файла.

Вывод всегда будет первым в списке столбца соединения, поэтому мы можем захотеть переместить его в правильное положение, поменяв местами два первых столбца, используяawk:

$ join -v 1 -t '|' -1 2 <( sort -t '|' -k2,2 fileA ) <( sort fileB ) | awk 'BEGIN { FS=OFS="|" } { t=$1; $1=$2; $2=t; print }'
2020-01-19|777504559|2|15|1|403941|53|4708267|3036|5033|127380343|0|3905585|C|1168|IRU|107|NR
2020-01-19|847082255|2|15|1|2|2|284|3036|291|125650195|125650195|8870299|C|1168|IRU|1|NR
2020-01-19|858760375|2|15|1|2|2|117|3036|109|2739523|5208959|4037061|C|1168|IRU|2|NR
2020-01-19|858760375|2|15|1|403941|53|4708267|3036|306|99931425|0|8866849|C|1168|IRU|107|NR
2020-01-19|869323039|2|15|1|2|2|371|3036|307|106104029|106104029|4518435|C|1168|IRU|2|NR
2020-01-19|872268371|2|15|1|403941|53|4708267|3036|143|127382679|0|8866849|C|1168|IRU|107|NR

Использование только awk:

$ awk -F '|' 'FNR==NR { key[$1]=1; next } !($2 in key)' fileB fileA
2020-01-19|777504559|2|15|1|403941|53|4708267|3036|5033|127380343|0|3905585|C|1168|IRU|107|NR
2020-01-19|847082255|2|15|1|2|2|284|3036|291|125650195|125650195|8870299|C|1168|IRU|1|NR
2020-01-19|858760375|2|15|1|403941|53|4708267|3036|306|99931425|0|8866849|C|1168|IRU|107|NR
2020-01-19|869323039|2|15|1|2|2|371|3036|307|106104029|106104029|4518435|C|1168|IRU|2|NR
2020-01-19|872268371|2|15|1|403941|53|4708267|3036|143|127382679|0|8866849|C|1168|IRU|107|NR
2020-01-19|858760375|2|15|1|2|2|117|3036|109|2739523|5208959|4037061|C|1168|IRU|2|NR

Сначала считывается число, которое мы хотим извлечь в ассоциативный массив key. Затем, когда второй файл анализируется, если второе поле не является ключом в этом массиве, печатается строка.

Это выведет строки из fileAв том порядке, в котором они встречаются в этом файле, но недостатком является то, что все числа из fileBдолжны храниться в памяти.


Использование Perl по запросу:

$ perl -F'\|' -le 'if (!$flag){ $key{$F[0]}=1 } elsif ($key{$F[1]}!=1) { print $_ }; if (!$flag && eof) { $flag=1 };' fileB fileA
2020-01-19|777504559|2|15|1|403941|53|4708267|3036|5033|127380343|0|3905585|C|1168|IRU|107|NR
2020-01-19|847082255|2|15|1|2|2|284|3036|291|125650195|125650195|8870299|C|1168|IRU|1|NR
2020-01-19|858760375|2|15|1|403941|53|4708267|3036|306|99931425|0|8866849|C|1168|IRU|107|NR
2020-01-19|869323039|2|15|1|2|2|371|3036|307|106104029|106104029|4518435|C|1168|IRU|2|NR
2020-01-19|872268371|2|15|1|403941|53|4708267|3036|143|127382679|0|8866849|C|1168|IRU|107|NR
2020-01-19|858760375|2|15|1|2|2|117|3036|109|2739523|5208959|4037061|C|1168|IRU|2|NR

Это имитирует программу awk, но поскольку Perl не имеет отдельных NRи FNR, встроенных -в переменные, нам нужно поддерживать некоторое состояние ($flag), которое сообщает нам, анализируем ли мы в данный момент первый или второй файл.

0
28.01.2020, 05:17

Теги

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