оболочка: сопоставление столбцов файла TSV с использованием отдельно определенного сопоставления

Я не знаю, как Linux обрабатывает правила Netfilter на уровне кода операции. Но многопортовый подход может выполнять несколько проверок за одну операцию.

Так как 1 Гбит/с не так много для процессора (даже медленного ), неудивительно, что вам нужны крайние случаи. Но оба подхода даже при одинаковой пропускной способности могут генерировать совершенно разные нагрузки. Поскольку это материал ядра, он, вероятно, даже не показан в /proc/loadavg. Таким образом, вам придется запустить приложение с интенсивным использованием ЦП -в той же системе и измерить его производительность, чтобы увидеть реальную разницу.

Но я думаю, что ваше сравнение несколько несправедливо, потому что мультипорт проверяет один раз для -p tcp, тогда как мультируль делает ту же самую проверку 65536 раз. Таким образом, вы бы сделали что-то вроде этого:

iptables -N tcp_ports
iptables -A INPUT -p tcp -j tcp_ports
for ((i=1;i<65536;i++)); do iptables -A tcp_ports --sport $i...

Я просто понимаю, что вы не можете пропустить проверку TCP, потому что это требование для --dport. Но это одна из причин, почему подход с несколькими правилами работает медленнее.

Я не уверен, что мультипорт предназначен для таких случаев, как ваш. Для сравнения были созданы огромные списки ipset. Так что это может быть то, что вы на самом деле ищете.

ipset create foo bitmap:port range tcp:10000-19999
ipset add foo tcp:10000-19999
iptables -A INPUT -p tcp -m set --match-set foo dst
-2
26.03.2020, 12:22
4 ответа

Поместите это в файл с именемmy_map_command:

#!/usr/bin/awk -f
FNR==NR{map[$1]=$2}
FNR!=NR{
    printf "%s%s",map[$1],OFS
    for (i=2; i<=NF; i++) printf "%s%s",$i,OFS
    printf "\n"
}

Затем запустите:

chmod u+x my_map_command

Вызовите свой скрипт как:

./my_map_command map.tsv data.tsv

Несколько файлов карты:

./my_map_command <(cat map1.tsv map2.tsv) data.tsv
2
19.03.2021, 02:32

Назначить переменную между аргументами файла:

awk '!data{map[$1]=$2; next} $1 in map{$1=map[$1]} 1' map1 map2... data=1 data
  • считывать значения в массив mapдо тех пор, пока не будет задан флаг
  • после того, как задано значение флага(data=1аргумент ), поменять поле в данных на сопоставленное значение

awk '
!data {
    map[field,$1]=$2
    maps[field]
    next
}
{
    for (i in maps)
        if ((i,$i) in map)
            $i=map[i,$i]
}
1' field=1 map1 field=2 map2 data=1 data
  • Поле 1 в dataсопоставляется со значением изmap1
  • Поле 2 в dataсопоставляется со значением изmap2
1
19.03.2021, 02:32

csvkit

Команда csvjoinиз пакета csvkit может использоваться для достижения аналогичного поведения:

$ csvjoin -tH -c 1,1 data.tsv map.tsv 2> /dev/null
a,b,c,b2
1,a,3,foo
2,b,2,bar
3,a,10,baz
2,c,2,bar
2,a,8,bar

Переупорядочить/удалить столбцы очень просто, и это можно сделать с помощью csvcutиз того же пакета.

основные утилиты

Стандарт join(1)тоже можно использовать, но он требует сортировки данных (и карты, если она не отсортирована):

$ join -j1 -t '       ' <(sort -k1 data.tsv) map.tsv
1       a       3       foo
2       a       8       bar
2       b       2       bar
2       c       2       bar
3       a       10      baz

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

2
19.03.2021, 02:32

Или просто используйте уже знакомый вам язык для опроса табличных данных:;

Синтаксис прост:q "<SQL Query>"или q -t "…", если ваши файлы имеют формат tsv, или -d …для других разделителей. Ваш запрос будет:

SELECT m.c2, d.c2, d.c3 
FROM data.tsv AS d INNER JOIN map.tsv AS m
                   ON d.c1==m.c1

q - text as data(упаковановезде)представляет собой удобный инструмент для применения возможностей SQL к любым табличным данным с разделителями. Даже STDIN работает, просто укажите « -» вместо имени файла, подумайте JOIN - as m, чтобы заменить map.tsv чем-то, что вы передаете.

Приятный "бонус"q:Вы можете использовать SQL ORDER, GROUP, а также производить вычисления! Показывая все это:

q 'SELECT m.c2 AS I, d.c2, d.c3, ROUND(d.c3*0.4, 2) as b
   FROM data.tsv AS d INNER JOIN - AS m
                      ON d.c1==m.c1
   ORDER BY I' < map.tsv

bar b 2 0.8
bar c 2 0.8
⋮

Примечание :Имя "q" полностью не гуглится, поэтому при поиске добавляйте "текст -как -данные" или "harelba" (автора ).

0
19.03.2021, 02:32

Теги

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