Сравните 60 больших файлов и выведите только те строки, которые являются общими для всех файлов

Вы можете настроить следующую командную строку с помощью «find» и «awk»

find FOLDERLIST -type f -iname "PATTERN" \
     -exec awk -F":" 'NF>1 {print $2}' "{}" \; > /PATH/TO/RESULTFILE

где

  • СПИСОК ПАПОК — это разделенный пробелами список верхних папок, в которых вы хотите выполнить рекурсивный поиск, при этом «текущая папка» будет представлять собой точку :find. -тип ф...
  • "-введите f" только для поиска файлов
  • ШАБЛОН — это общий шаблон файлов, которые вас интересуют, например. звездочка "*" найдет все файлы, "*.csv" найдет файлы CSV,...
  • /PATH/TO/RESULTFILE — это имя вашего файла результатов в корневом каталоге
  • часть "awk" разбивает все найденные файлы на " :" и пропускает пустые результаты

РЕДАКТИРОВАТЬ :изменена проверка пустых результатов на NF>1, как было предложено steeldriver.

2
23.06.2020, 12:43
4 ответа

Попробуйте это,

awk '
    BEGINFILE{fnum++; delete f;}
    !f[$0]++{s[$0]++;}
    END {for (l in s){if (s[l] == fnum) print l}}
' files*

Пояснение:

  • BEGINFILE {... }Запускать в начале каждого файла

  • !f[$0]++ {... }Выполнять только при первом появлении строки в файле (, если f[$0]равно 0 (false))

    • s[$0]++Строка приращения счетчика -.
  • END {... }Выполнить один раз в конце

    • for (l in s){if (s[l] == fnum) print l}Зациклить строки и вывести каждую, где количество вхождений равно количеству файлов.

Памяти должно хватить на 600 000 строк. В противном случае вы можете удалить из sвсе, что меньше fnumв блоке BEGINFILE{...}.

1
18.03.2021, 23:24

С zsh, используя его ${a:*b}оператор пересечения массивов для массивов, помеченных уникальным флагом (, также используя $(<file)оператор ksh и fфлаг раскрытия параметра для разделения на символы перевода строки):

#! /bin/zsh -
typeset -U all list
all=(${(f)"$(<${1?})"}); shift
for file do
  list=(${(f)"$(<$file)"})
  all=(${all:*list})
done
print -rC1 -- $all

(этот скрипт принимает в качестве аргументов список файлов; пустые строки игнорируются ).

0
18.03.2021, 23:24

Сjoin:

cp a jnd
for f in a b c; do join jnd $f >j__; cp j__ jnd; done

У меня просто числа (1 -6, 3 -8, 5 -9 )в трех файлах a, b и c. Это две строки (, числа, строки ), которые имеют общее.

]# cat jnd
5
6

Это не элегантно/эффективно, особенно с этим cpмежду ними. Но его можно легко заставить работать параллельно. Выберите подгруппу файлов (for f in a*), дайте файлам уникальные имена, после чего вы сможете запускать несколько подгрупп одновременно. Вам все еще нужно объединить эти результаты... -с 64 файлами у вас будет 8 потоков, объединяющих по 8 файлов в каждом, а затем оставшиеся 8 объединенных файлов можно снова разделить на 4 потока.

0
18.03.2021, 23:24

Параллельная версия в bash. Это должно работать для файлов больше, чем память.

export LC_ALL=C
comm -12 \
  <(comm -12 \
    <(comm -12 \
      <(comm -12 \
        <(comm -12  <(comm -12  <(sort 1) <(sort 2);) <(comm -12  <(sort 3) <(sort 4););) \
        <(comm -12  <(comm -12  <(sort 5) <(sort 6);) <(comm -12  <(sort 7) <(sort 8);););) \
      <(comm -12 \
        <(comm -12  <(comm -12  <(sort 9) <(sort 10);) <(comm -12  <(sort 11) <(sort 12););) \
        <(comm -12  <(comm -12  <(sort 13) <(sort 14);) <(comm -12  <(sort 15) <(sort 16););););) \
    <(comm -12 \
      <(comm -12 \
        <(comm -12  <(comm -12  <(sort 17) <(sort 18);) <(comm -12  <(sort 19) <(sort 20););) \
        <(comm -12  <(comm -12  <(sort 21) <(sort 22);) <(comm -12  <(sort 23) <(sort 24);););) \
      <(comm -12 \
        <(comm -12  <(comm -12  <(sort 25) <(sort 26);) <(comm -12  <(sort 27) <(sort 28););) \
        <(comm -12  <(comm -12  <(sort 29) <(sort 30);) <(comm -12  <(sort 31) <(sort 32);););););) \
  <(comm -12 \
    <(comm -12 \
      <(comm -12 \
        <(comm -12  <(comm -12  <(sort 33) <(sort 34);) <(comm -12  <(sort 35) <(sort 36););) \
        <(comm -12  <(comm -12  <(sort 37) <(sort 38);) <(comm -12  <(sort 39) <(sort 40);););) \
      <(comm -12 \
        <(comm -12  <(comm -12  <(sort 41) <(sort 42);) <(comm -12  <(sort 43) <(sort 44););) \
        <(comm -12  <(comm -12  <(sort 45) <(sort 46);) <(comm -12  <(sort 47) <(sort 48););););) \
    <(comm -12 \
      <(comm -12 \
        <(comm -12  <(comm -12  <(sort 49) <(sort 50);) <(comm -12  <(sort 51) <(sort 52););) \
        <(comm -12  <(comm -12  <(sort 53) <(sort 54);) <(comm -12  <(sort 55) <(sort 56);););) \
      <(cat  <(comm -12  <(comm -12  <(sort 57) <(sort 58);) <(comm -12  <(sort 59) <(sort 60););) ;);););

Замените sortна cat, если файлы уже отсортированы.

1
18.03.2021, 23:24

Теги

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