Поиск общих черт между 6 файлами

Вам нужно немного узнать об ARP-кэшах, прежде чем вы сможете эффективно интерпретировать вывод ARP-кэша

Кэш arp содержит сопоставления IP :MAC-адреса для:

  • Размещает обмен трафиком между вашим сервером В СВОЕЙ СОБСТВЕННОЙ ПОДСЕТИ

  • Интерфейсы маршрутизатора, используемые для маршрутизации трафика между вашим хостом и другими в РАЗНЫХ подсетях

ARP-кэш этих сопоставлений IP:MAC-адресов НЕ сохраняется:

  • Сеть перезапуск.

  • Сервер перезагружается.

Хотя Garbage Collection("gc")должнаочищать в вашем arp-кэше эти сопоставления, которые превышают указанный GC порог, реальность они сохраняются,хотя записано как « просроченный »

Таким образом, вы не увидите сопоставлениеIP-адресов :MAC-адресовхоста, с которым ваш сервер обменивался трафиком, адресованного вДРУГОЙподсети или даже в одной из подсетей вашего хоста. подсети, если сеть или сам сервер были перезапущены.

Кстати, если вы хотите проверить устойчивость сопоставлений за пределами интервалаGC , pingдругой хост в той же подсети и после остановки pingпериодически выполняйте:

ip -statistics neighbour

Вы увидите IP-адрес :MAC-адрес хоста, который вы pingуказали, после интервала GC .

3
12.03.2021, 14:09
4 ответа

С помощью awkможно сделать следующее:

#skip if multiple appearance in one file
{if ( seenin[$0] ~ FILENAME ) {next}}
#add filename to list of files the line has been seen in, increase seen counter
{seenin[$0]=seenin[$0]" "FILENAME ; nseen[$0]++}

#print
END {for (line in nseen) { if (nseen[line]>1) {
   printf "%s \"%s\" %s %d %s %s\n",
     "line",line,"seen in",nseen[line],"files:",seenin[line]} } }

Ограничение :памяти, так как все строки сохраняются в ОЗУ.

Если вы хотите отсортировать по количеству вхождений, команда печати должна быть адаптирована соответствующим образом, например. сортировать по значениям nseen. С gawkэто просто :в блоке ENDдобавьте это перед цикломfor-:

PROCINFO["sorted_in"]="@val_num_desc"

Входные файлы:

$ cat file1
a
a
b
b
c
d
e

$ cat file2
c
c
x
z
e
y
z
f

$ cat file3
f
i
a
c
z
i
k

вывод (с gawkвозможностью обхода массива черезPROCINFO)

$awk -f compare_lines_multifiles.awk file1 file2 file3
line "c" seen in 3 files:  file1 file2 file3
line "z" seen in 2 files:  file2 file3
line "a" seen in 2 files:  file1 file3
line "e" seen in 2 files:  file1 file2
line "f" seen in 2 files:  file2 file3

РЕДАКТИРОВАТЬ:

Предоставленные вами файлы имеют формат MSDOS. Либо конвертируйте их через

 dos2unix file1.txt file2.txt....

или настройте разделитель записей в awk. В качестве первой записи в коде добавьте это:

 BEGIN { RS="\r\n" }

РЕДАКТИРОВАТЬ 2 :Ваши файлы имеют неправильные разделители. Проблема в том, что a<tab>bи a<tab>b<tab>считаются разными строками, а вы можете считать их одинаковыми.

Для вашего очень особого случая с двумя интересующими полями в файлах вы скорее захотите сравнить содержимое этих двух полей, а не полных строк. Также с учетом формата MSDOS -:

BEGIN { RS="\r\n" }
#skip if multiple appearance in one file
{if ( seenin[$1"\t"$2] ~ FILENAME ) {next}}
#add filename to list of files the line has been seen in, increase seen counter
{seenin[$1"\t"$2]=seenin[$1"\t"$2]" "FILENAME ; nseen[$1"\t"$2]++}

#print
END {for (line in nseen) { if (nseen[line]>1) {
   printf "%s \"%s\" %s %d %s %s\n",
     "line",line,"seen in",nseen[line],"files:",seenin[line]} } }

В результате все шесть файлов перекрываются гораздо сильнее. Он фокусируется на двух полях с разделителем табуляции и печатает вывод строки как таковой.

3
18.03.2021, 22:25

Я предлагаю другой подход. Просто пропустите их через sortи uniq -c, чтобы подсчитать, сколько раз была просмотрена каждая строка :

.
sort 2.txt 3.txt 4.txt 5.txt 6.txt 7.txt | uniq -c

Каждая строка будет выведена один раз, но также будет выведено количество просмотров строки. Например,если у меня есть эти три файла:

$ cat file1 
dog
cat
bird

$ cat file2
fly
bird
moose

$ cat file3
bird
dog
flea

Я бы получил такой вывод:

$ sort file1 file2 file3 | uniq -c
      3 bird
      1 cat
      2 dog
      1 flea
      1 fly
      1 moose
    

Итак, если вы хотите разделить строки по количеству раз, когда они были найдены, вы можете сделать что-то вроде этого, чтобы увидеть только строки, которые появляются во всех 3 (или 6, в вашем случае )файлов:

$ sort file1 file2 file3 | uniq -c | awk '$1==3'
  3 bird
$ sort file1 file2 file3 | uniq -c | awk '$1==2'
      2 dog
$ sort file1 file2 file3 | uniq -c | awk '$1==1'
      1 cat
      1 flea
      1 fly
      1 moose
2
18.03.2021, 22:25
# spits a random three char (a..e)
# string each time it's called
rx() {
  < /dev/urandom \
  tr -cd 'a-e'   |
  fold -w3       |
  head -n 1      \
  ;
}

# modify this section
numFiles=6
numLines=70
commIn=5

# generate random files
for j in $(seq "$numFiles"); do
  for i in $(seq "$numLines"); do
    rx
  done > $j.txt
done

# uniquify each file
# then sort the combined pool
# count n tabulate uniques from this pool
for i in $(seq "$numFiles"); do
  sort -u < "$i.txt"
done                  |
sort | uniq -c        |
sort -b -k1,1nr -k2,2 |
awk -v n="$commIn" '$1+0==n'   ;

Результат этого прогона:

      5 acc
      5 bcd
      5 dac
      5 eea
0
18.03.2021, 22:25

Ваша первая попытка — правильный подход:

comm -12 2.txt 3.txt | comm -12 - 4.txt | comm -12 - 5.txt | comm -12 - 6.txt | comm -12 - 7.txt

Это работает как соединение параллельно как поток. В принципе, таким образом можно обрабатывать файлы с миллионами строк.

Проблема с comm(1 ), по-видимому, была вызвана проблемами ввода, а именно пробелами и концами строк. Если вы сначала очистите их, вы можете обнаружить, что ваш первоначальный подход и быстр, и удобен.

Вот пример, подтверждающий это. Найдите числа, которые делятся на наборы простых чисел:

$ for D in 2 3 5 7 11 13 
> do seq 1 1000 | 
> awk -v D=$D '$0 % D == 0 { print $0 }' | 
> sort > $D
> done

$ comm -12 2 3 | comm -12 - 5 | comm -12 - 7 
210
420
630
840

Оказывается, между 1 и 1000 нет чисел, которые делятся на 2, 3, 5, 7 и 11.

1
18.03.2021, 22:25

Теги

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