сравните два столбца различных файлов и печати, если она соответствует

Ваш новый раздел (/dev/sda4) сразу после /dev/sda3, который должен сделать вещи простыми.

Начальная загрузка с gparted живого CD (который, с Вашего /dev/sr0, кажется, что Вы уже имеете), и затем изменение размеров /dev/sda3 должен работать, но создать резервную копию, Ваши / размещают сначала (у Вас могло бы быть повреждение жесткого диска, если Вы теряете питание, Вашу виртуальную машину или размещаете замораживания/катастрофические отказы ОС, и т.д....).

16
18.09.2016, 04:34
4 ответа

Я думаю

grep -Ff file2 file1

это то, что вы ищете. Оно должно быть эффективным, но я не уверен, что оно будет настолько точным, насколько вы хотите. Если abc|123 (например) найден в строке в файле 1 в разных колонках, то эта строка также будет выведена. Если вы можете гарантировать, что этого никогда не случится, вышеуказанная строка должна сработать.

1
27.01.2020, 19:48

Это то, для чего была разработана awk:

$ awk -F'|' 'NR==FNR{c[$1$2]++;next};c[$1$2] > 0' file2 file1
abc|123|BNY|apple|
cab|234|cyx|orange|

Объяснение

  • -F '|' : устанавливает разделитель полей на | .
  • NR == FNR : NR - номер текущей строки ввода, а FNR - номер строки текущего файла. Эти два будут равны только при чтении 1-го файла.
  • c [$ 1 $ 2] ++; next : если это 1-й файл, сохраните первые два поля в массиве c . Затем перейдите к следующей строке, чтобы применить ее только к 1-му файлу.

  • c [$ 1 $ 2]> 0 : блок else будет выполняться только в том случае, если это второй файл, поэтому мы проверяем, были ли уже просмотрены поля 1 и 2 этого файла ( c [$ 1 $ 2 ]> 0 ), и если они были, печатаем строку. В awk действием по умолчанию является печать строки, поэтому, если c [$ 1 $ 2]> 0 истинно, строка будет напечатана.


В качестве альтернативы, поскольку вы отметили Perl:

perl -e 'open(A, "file2"); while(<A>){/.+?\|[^|]+/ && $k{$&}++};
         while(<>){/.+?\|[^|]+/ && do{print if defined($k{$&})}}' file1

Объяснение

Первая строка откроет file2 , прочтите все до 2-го | (. + ? \ | [^ |] + ) и сохраните это ( $ & является результатом последнего оператора сопоставления) в хэше % k .

Вторая строка обрабатывает file1, использует то же регулярное выражение для извлечения первых двух столбцов и печати строки, если эти столбцы определены в хэше % k .


Оба вышеупомянутых подхода должны будут содержать в памяти 2 первых столбца file2. Это не должно быть проблемой, если у вас всего несколько сотен тысяч строк, но если это так, вы можете сделать что-то вроде

cut -d'|' -f 1,2 file2 | while read pat; do grep "^$pat" file1; done

, но это будет медленнее.

21
27.01.2020, 19:48
$  sed 's/^/\^/' 2.txt > temp.txt ; grep 1.txt -f temp.txt
abc|123|BNY|apple|
cab|234|cyx|orange|
0
27.01.2020, 19:48

Если вы хотите обдумать проблему на языке SQL, то вам определенно стоит попробовать инструмент под названием 'q':

$ q -d '|' "select f1.* from file1 f1 join file2 f2 on (f1.c1 = f2.c1 and f1.c2 = f2.c2)"

Он более ясен и прост для понимания, если вы знакомы с SQL-запросами.

1
27.01.2020, 19:48

Теги

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