удаление начальных нулей с IP-адресов: преобразование ipfilter.dat в bluetack.co.uk ipfilter с помощью sed - PullRequest
0 голосов
/ 01 апреля 2011

Мне нужно было преобразовать ipfilter.dat в стиле uTorrent в файл ipfilter в стиле bluetack, и я написал этот сценарий оболочки для достижения этой цели:

#!/bin/bash

# read ipfilter.dat-formatted file line by line
# (example: 000.000.000.000-008.008.003.255,000,Badnet
# - ***here, input file's lines/fields are always the same length***)
# and convert into a bluetack.co.uk-formatted output
# (example: Badnet:0.0.0.0-8.8.3.255
# - fields moved around, leading zeros removed)

while read record
do
start=`echo ${record:0:15} | awk -F '.' '{for(i=1;i<=NF;i++)$i=$i+0;}1' OFS='.'`
end=`echo ${record:16:15} | awk -F '.' '{for(i=1;i<=NF;i++)$i=$i+0;}1' OFS='.'`
echo ${record:36:7}:${start}-${end}
done < $1

Однако для входного файла из 2000 строквыполнение этого скрипта занимает в среднем 10 (!) секунд - всего 200 строк / сек.

Я уверен, что такого же результата можно добиться с помощью sed, а sed-версия, вероятно, будет намного быстрее.

Есть ли вокруг себя сед-гуру, чтобы предложить решение для такого рода замен фиксированных позиций?

Не стесняйтесь предлагать решение и на других языках - я бы с удовольствием протестировал Pythonили версия C, например.Также будет приветствоваться более эффективная версия оболочки / bash.

Ответы [ 4 ]

1 голос
/ 01 апреля 2011

Вы будете жертвовать производительностью, используя цикл чтения во время чтения большого файла.Опытным путем доказано, что такие инструменты, как awk/sed (и некоторые языки, например, Perl / Python / Ruby), лучше выполняют итерации больших файлов и обрабатывают строки, чем оболочка во время цикла чтения.Более того, в вашем скрипте, перебирая строки, вы также отправляете несколько вызовов на awk.Это дополнительные накладные расходы.

Рубин (1,9 +)

$ cat file
000.000.000.000-008.008.003.255,000,Badnet
001.010.110.111-002.020.220.222,111,Badnet

$ ruby -F"," -ane 'puts "#{$F[-1].chomp}:" + $F[0].gsub(/(00|0)([0-9]+)([.-])/,"\\2\\3")'   file
Badnet:0.0.0.0-8.8.3.255
Badnet:1.10.110.111-2.20.220.222
1 голос
/ 01 апреля 2011

Вы можете попробовать это.

sed -r 's/^0*([0-9]+)\.0*([0-9]+)\.0*([0-9]+)\.0*([0-9]+)-0*([0-9]+)\.0*([0-9]+)\.0*([0-9]+)\.0*([0-9]+),...,(.*)$/\9:\1.\2.\3.\4-\5.\6.\7.\8/' inputfile

Я не тестировал производительность, но думаю, что она может быть быстрее 200 строк / сек.

0 голосов
/ 16 июня 2015

#!/bin/tclsh

#Regsub TCL script to remove the leading zeros from the ip address.

#Author : Shoeb Masood , Bangalore

puts "Enter the ip address"
set ip [gets stdin]
set list_ip [split $ip .]
foreach index $list_ip {
regsub  {^0|^00} $index {\1} index
lappend list_ip2 $index
}
set list_ip2 [join $list_ip2 "."]
puts $list_ip2
0 голосов
/ 01 апреля 2011

Я действительно хотел, чтобы это работало в одной команде sed, но я не смог понять это.Конечно, это все равно будет быстрее, чем 200 строк / с.

sed 's/\.0\{1,2\}/\./g' | sed 's/^0\{1,2\}//'

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...