LINUX.ORG.RU
ФорумAdmin

Bash: как строчку саб домена рас'split'ить на строчки из всех выше него стоящих.

 ,


1

2

Собственно сабж.
Есть жЫрный простыня-лист со списком доменов. Всяких разных.
Нужно на баше понятным образом получить из sub4.sub3.sub2.domain.lol
sub3.sub2.domain.lol
sub2.domain.lol
domain.lol
Причем domain.lol сплитить не надо. (в смысле что .lol не нужон строчкой)


Ответ на: комментарий от gnu_linux

-=:=-

Усталость. мозги кипят.
Я до этого чистил этот список от говна в виде кривых ссылок, битых доменных имен...
просто устал...

KosmiK ()
<file awk -F. '{print $(NF-1)"."$NF}' >newfile
legolegs ★★★★★ ()

Ну вроде вот работает:

IFS=.
while read -a dms; do
        [[ ${#dms[*]} -eq 2 ]] && echo "${dms[*]}"
        for((i=${#dms[*]};i>2;i--)); do
                echo "${dms[*]:i-2}"
        done
done

vodz ★★★★★ ()
Последнее исправление: vodz (всего исправлений: 1)

-=:=-

Та лан посоны, я уже на'кал'хозил

#!/bin/bash
for serverstring in $(cat "./start"); do
    echo "$serverstring" | cut -d '.' -f2- >> list
    echo "$serverstring" | cut -d '.' -f3- >> list
    echo "$serverstring" | cut -d '.' -f4- >> list
    echo "$serverstring" | cut -d '.' -f5- >> list
    echo "$serverstring" | cut -d '.' -f6- >> list
    echo "$serverstring" | cut -d '.' -f7- >> list
    echo "$serverstring" | cut -d '.' -f8- >> list
done

cat start >> temp-end
cat list | sort -u | grep "\." >> temp-end
cat temp-end | sort -u > end
rm -f list
rm -f temp-end


и

#!/bin/bash
echo '/ip firewall address-list' > script.rsc

for serverd in $(cat "./input.txt"); do
    server=$(echo "$serverd" | idn)
    echo 'add address='"$server"' list=PUBLIC-LESSON' >> script.rsc
done

KosmiK ()
Ответ на: -=:=- от KosmiK

-=:=-

Кстате, как думаете: 30880 строк листинга буду съедены микроТыком, как белый листдля пропуска спиногрызоф в энти интарнеты?

KosmiK ()
Ответ на: -=:=- от KosmiK

Re: -=:=-

Микротыков много. Да и нагрузка бывает разная. Но на него Nginx со подменой контента на лету ставят. Так что париться не о чем.

anonymous ()
Ответ на: комментарий от legolegs

Неужели я опять не понял задачу? Судя по описанию это вырисовалось так:

  • для . - не выводить ничего
  • для tld. - тоже ничего
  • для dom.tld выводить неизменное dom.tld
  • для sub1.dom.tld выводить только dom.tld
  • для sub2.sub1.dom.tld выводить и sub1.dom.tld и dom.tld
  • и так далее без sub_first все до dom.tld

Разве нет?

vodz ★★★★★ ()

-=:=-

#!/bin/bash
for serverstring in $(cat "./start"); do
    vartemp="true"
    tempstart=$serverstring
    echo "$tempstart" >> temp-list
    while [ "$vartemp" = "true" ]; do
        tempnext=$(echo "$tempstart" | cut -d '.' -f2- | grep "\.")
        if [ ! -z "$tempnext" ]
        then
            echo "$tempnext" >> temp-list
            tempstart=$tempnext
        else
            vartemp="false"
        fi
    done
done

cat temp-list | sort -f -u > end-list
rm -f temp-list


И это работает лучше. И нет пропусков доменов.

KosmiK ()
Последнее исправление: KosmiK (всего исправлений: 1)
Ответ на: -=:=- от KosmiK

Я вот посмотрел что делает ваш скрипт и увидел, что оригинальный домен вы тоже выводите, что было не очевидно из ТЗ. А также вы не любите bash и пишете в ash-стиле. Переписал на ash, получилось даже понятнее, хоть и чуть длиннее:

convert() {
        local IFS=. l
        set -f
        while read -r l; do
                set -- $l
                while true; do
                        echo "$*"
                        [ $# -le 2 ] && break
                        shift
                done
        done
        set +f
}

convert < start > end-list

vodz ★★★★★ ()
Ответ на: комментарий от vodz

Я так поначалу (неправильно) понял, что топикстартеру надо из

sub4.sub3.sub2.domain.lol
sub3.sub2.domain.lol
sub2.domain.lol

получить domain.lol (с мобильника оно всё в один столбик было написано).

А ему, оказывается, надо из

sub4.sub3.sub2.domain.lol

сделать

sub4.sub3.sub2.domain.lol
sub3.sub2.domain.lol
sub2.domain.lol
domain.lol

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

legolegs ★★★★★ ()
Ответ на: комментарий от legolegs

но чётко и ясно это было написать в виде примера нельзя

Угу, только разбирая его портянки я увидел, что оригинал тоже выводится. Скрипт в предыдущем комменте получился красивый, мне самому нра, и думаю он достоин для занесения в демо-образцы, где ash даже не ухудшает качества.

тех кто так может полиция в интернет не пускает

Заметил другую вещь на ЛОРе, ТСы не обращают внимания на комментарии, кодят что-то своё как могут и хорошо ещё, что разговаривают сами с собой, а то и вообще молчат и думай что хочешь.

vodz ★★★★★ ()
Ответ на: комментарий от vodz

предыдущем комменте получился красивый

Соглашусь, вполне элегантный скрипт. И быстрый.

Никому не нужные тесты ahead:

</dev/urandom tr -cd 'a-z.\n' |
    egrep -ao '([a-z]{2,5}\.){3,5}[a-z]{2,3}' |
    head -n 5000 > domains5k
for i in  KosmiK.sh KosmiK2.sh vodz.sh vodz2.sh ; do
    echo '>'$i
    time ./$i
    sort end > end_${i}.txt
    rm end
done

Тестовые домены вида

jilpg.cvj.pl.viy.qby
pxcll.fz.op.ooy
hxfkg.ecn.efsqx.pbu
vncjz.phxjv.jrhrq.sjf
>KosmiK.sh

real    0m36,815s
user    0m20,833s
sys     0m29,138s
>KosmiK2.sh

real    0m35,516s
user    0m19,290s
sys     0m36,610s
>vodz.sh

real    0m0,232s
user    0m0,189s
sys     0m0,042s
>vodz2.sh

real    0m0,226s
user    0m0,191s
sys     0m0,035s

Результаты совпали побайтово.

legolegs ★★★★★ ()
Последнее исправление: legolegs (всего исправлений: 1)
Ответ на: комментарий от legolegs

То, что моя грепалка рандома такие не выдаёт

Медленная у вас грепалка, странные ограничения... Вот вроде шустро работает:

base64 -w 512 </dev/urandom | tr '[0-9]+/' ... | grep -Eo '([^.]+\.){1,5}[^.]{2,}'

vodz ★★★★★ ()
Последнее исправление: vodz (всего исправлений: 1)

Как только люди не извращаются, лишь бы openwrt+dnsmasq+ipset не настраивать

pekmop1024 ★★★★★ ()

-=:=-

Вообщем это, пачаны, я Вам тут покушать принес..глядите как shit'ever:

localhost /home/scripts/dns-ip-convert # cat nslookup-for-openvpn.bash
#!/bin/bash
ifconfig tun0 2>/dev/null 1>/dev/null
RESULT=$?
if [ $RESULT -eq 0 ]; then
    defgw=$(ifconfig tun0 2>/dev/null | grep -i "inet 10." | awk '{print $2}' | cut -d "." -f 2)
else
    defgw="96"
fi

cd /home/scripts/dns-ip-convert
#
# List of excluded ip's
#

#cat /var/log/named/queries.log | grep -v " 127.0.0.1#" | awk '{print $8}' | grep googlevideo.com  > /tmp/youtube.exclude.list
#cat /var/log/named/queries.log | grep -v " 127.0.0.1#" | awk '{print $8}' | grep ytimg.com  >> /tmp/youtube.exclude.list
#cat ./names-exclude/youtube.exclude.list >> /tmp/youtube.exclude.list
#cat /tmp/youtube.exclude.list | sort -u > ./names-exclude/youtube.exclude.list
#rm -f /tmp/youtube.exclude.list

for company in google origin steam bioware meduza adobe intel steelseries gitlab ubisoft other teamviewer ebay; do
    if [ -f "./names-exclude/$company.exclude.list" ]
    then
        for serverex in $(cat "./names-exclude/$company.exclude.list"); do
            nslookup $serverex | grep Address | grep -v "127.0.0.1" | awk '{print $2}' | grep -v "#" | grep -v "::" | sort -u | sort  -t . -k 1,1n -k 2,2n -k 3,3n -k 4,4n >> /tmp/ip-exclude.$company.temp
        done

#       cat ./ip-exclude/$company.ex.list >> /tmp/ip-exclude.$company.temp
#       cat /tmp/ip-exclude.$company.temp | sort -u | sort -t . -k 1,1n -k 2,2n -k 3,3n -k 4,4n > ./ip-exclude/$company.ex.list

#       for ip in $(cat ./ip-exclude/$company.ex.list); do
#           route del -host "$ip" gw "10.$defgw.0.1" dev tun0  1>/dev/null 2>/dev/null
#       done
    fi
#
# List of routing ip's
#
    if [ -f "./names/$company.name.list" ]
    then
        for server in $(cat "names/$company.name.list"); do
            temptemp=$(nslookup $server | grep Address | grep -v "127.0.0.1" | awk '{print $2}' | grep -v "#" | grep -v "::" | sort -u | sort  -t . -k 1,1n -k 2,2n -k 3,3n -k 4,4n)
            nslookup $server | grep Address | grep -v "127.0.0.1" | awk '{print $2}' | grep -v "#" | grep -v "::" | sort -u | sort  -t . -k 1,1n -k 2,2n -k 3,3n -k 4,4n >> /tmp/ip.temp
#           echo $temptemp >> /tmp/ip.temp
#           echo $temptemp >> /home/Storage-2TB/dns_names/$server
        done

        cat ip/$company.ip.list >> /tmp/ip.temp

#       if [ -f "./names-exclude/$company.exclude.list" ]
#       then
#           cat /tmp/ip.temp | grep -v "::" | grep -v -f ./ip-exclude/$company.ex.list | sort -u | sort  -t . -k 1,1n -k 2,2n -k 3,3n -k 4,4n > /tmp/ip.temp2 && rm -f /tmp/ip.temp
#       else
            cat /tmp/ip.temp | grep -v "::" | sort -u | sort  -t . -k 1,1n -k 2,2n -k 3,3n -k 4,4n > /tmp/ip.temp2 && rm -f /tmp/ip.temp
#       fi
        mv /tmp/ip.temp2 ip/$company.ip.list
        cp -f ip/$company.ip.list /etc/ppp/routing-hosts/$company.list
    fi
done

for ip in $(cat /etc/ppp/routing-hosts/* | sort -u -t . -k 1,1n -k 2,2n -k 3,3n -k 4,4n); do
    route add -host $ip gw "10.$defgw.0.1" dev tun0  1>/dev/null 2>/dev/null
done

KosmiK ()
Ответ на: комментарий от legolegs

-=:=-

А если так?

#!/bin/bash
MYPATH="/home/scripts/dns-ip-convert"
cd "$MYPATH"

temp1=$(ifconfig tun0 2>&1 | grep -i "inet 10." | awk '{print $2}' | cut -d "." -f 2)
[ ! -z "$temp1" ] && defgw="$temp1" || defgw="96"
unset temp1

resolver() {
    while read -r strx; do
        nslookup $strx 2>&1 | grep "Address:\ " | grep -v "127.0.0.1" | awk '{print $2}' | grep -v "#" | grep -v "::" | sort -u -t . -k 1,1n -k 2,2n -k 3,3n -k 4,4n
    done
}

routeit() {
    while read -r ip; do
        route add -host $ip gw "10.$defgw.0.1" dev tun0 1>/dev/null 2>/dev/null
    done
}

for company in google origin steam bioware meduza adobe intel steelseries gitlab ubisoft other teamviewer ebay; do
    if [ -f "./names/$company.name.list" ]
    then
        resolver < ./names/$company.name.list >> /tmp/ip.temp
        cat ip/$company.ip.list /tmp/ip.temp | grep -v "::" | tr " " "\n" | sort -u -t . -k 1,1n -k 2,2n -k 3,3n -k 4,4n > /tmp/ip2.tmp

        if [[ $(sha512sum './ip/'$company'.ip.list' | awk '{print $1}') != $(sha512sum '/tmp/ip2.tmp' | awk '{print $1}') ]]
        then
            routeit < /tmp/ip2.tmp
            cp -f /tmp/ip2.tmp ./ip/$company.ip.list
            mv /tmp/ip2.tmp /etc/ppp/routing-hosts/$company.list
        fi
        rm -f /tmp/ip.temp 2>/dev/null 1>/dev/null

    fi
done

KosmiK ()
Последнее исправление: KosmiK (всего исправлений: 1)
Ответ на: -=:=- от KosmiK

Менее безумные версии некоторых частей твоего скрипта:

resolver() {
  nslookup -type=A - |
    awk '/Address: / && !/127.0.0.1/ {print $2}' |
    sort -u -t . -k 1,1n -k 2,2n -k 3,3n -k 4,4n
}

....

if ! cmp './ip/'$company'.ip.list' '/tmp/ip2.tmp' 

legolegs ★★★★★ ()
Последнее исправление: legolegs (всего исправлений: 2)
Ответ на: комментарий от legolegs

-=:=-

Получилось так

#!/bin/bash
MYPATH="/home/scripts/dns-ip-convert"
cd "$MYPATH"

temp1=$(ifconfig tun0 2>&1 | grep -i "inet 10." | awk '{print $2}' | cut -d "." -f 2)
[ ! -z "$temp1" ] && defgw="$temp1" || defgw="96"
unset temp1

resolver() {
    while read -r strx; do
        nslookup -type=A "$strx" 2>&1 | awk '/Address: / && !/127.0.0.1/ {print $2}' | sort -u -t . -k 1,1n -k 2,2n -k 3,3n -k 4,4
    done
}

routeit() {
    while read -r ip; do
        route add -host "$ip" gw "10.$defgw.0.1" dev tun0 1>/dev/null 2>/dev/null
    done
}

unrouteit() {
    while read -r ip; do
        route del -host "$ip" gw "10.$defgw.0.1" dev tun0 1>/dev/null 2>/dev/null
    done
}

for company in google origin steam bioware meduza adobe intel steelseries gitlab ubisoft other teamviewer ebay; do
# List of routing ip's
#
    if [ -f "./names/$company.name.list" ]
    then
        resolver < ./names/$company.name.list >> /tmp/ip.temp
        cat ip/$company.ip.list /tmp/ip.temp | grep -v "::" | tr " " "\n" | sort -u -t . -k 1,1n -k 2,2n -k 3,3n -k 4,4n > /tmp/ip2.tmp
        if cmp './ip/'"$company"'.ip.list' '/tmp/ip2.tmp' -s; then
            rm -f /tmp/ip2.tmp 2>/dev/null 1>/dev/null
        else
            routeit < /tmp/ip2.tmp
            cp -f /tmp/ip2.tmp ./ip/$company.ip.list
            mv /tmp/ip2.tmp /etc/ppp/routing-hosts/$company.list
        fi

        rm -f /tmp/ip.temp 2>/dev/null 1>/dev/null
    fi

# List of unwanted for routing ip's
#
    if [ -f "./names-exclude/$company.exclude.list" ]
    then
        resolver < ./names-exclude/$company.exclude.list > /tmp/ip-exclude.$company.temp
        unrouteit < /tmp/ip-exclude.$company.temp
        rm -f /tmp/ip-exclude.$company.temp 2>/dev/null 1>/dev/null
    fi
done


Но вот как переделать это:
temp1=$(ifconfig tun0 2>&1 | grep -i "inet 10." | awk '{print $2}' | cut -d "." -f 2)
[ ! -z "$temp1" ] && defgw="$temp1" || defgw="96"
unset temp1

да еще и в одну строчку

KosmiK ()
Ответ на: -=:=- от KosmiK

while read -r strx; do

Там цикл вообще не нужен, nslookup в интерактивном режиме обрабатывает строки с именами последовательно, не надо было менять ничего.

Но вот как переделать это:

Не совсем понимаю, зачем получать именно второй октет адреса, но можно, например, так:

var=$(ifconfig tun0 | awk '
  $1~/inet/ {
    FS=".";
    $0=$2;
    octet2=$2;
  }
  END {
    print octet2?octet2:96
  }')

Хотя если тебе нужен адрес шлюза, то его проще и правильнее взять из таблицы маршрутизации

gw=$(route -n | awk '$4 == "UG" {print $2}')

Зря ты везде пихаешь 2>&1. Если одна из утилит начнёт сообщать об ошибках - это сломает парсинг и спрячет ошибку от админа.

legolegs ★★★★★ ()
Ответ на: комментарий от legolegs

Не совсем понимаю, зачем получать именно второй октет адреса,

Сеть у него небось 10.N/16 .

но можно, например, так:

Чисто стилистически правильнее у ТСа, когда проверка не внутри awk, а снаружи. Сегодня там тернарная на 96, а завтра условие усложнится...

И вообще, что за желание пихать кучу вызовов awk для обработки 5 строчек от ifconfig? Ладно бы было тысячи строк... Ведь так он и не научится программировать на bash и продожит генерировать эти портянки с кучей пайпов и временных файлов.

vodz ★★★★★ ()
Ответ на: комментарий от vodz

Чисто стилистически правильнее у ТСа, когда проверка не внутри awk, а снаружи

Да, пожалуй.

octet2=$(ifconfig tun0 | awk '
  $1~/inet$/ {
    FS=".";
    $0=$2;
    print $2;
  }')
[ ! -z "$octet2" ] && defgw="$octet2" || defgw="96"
unset octet2

И вообще, что за желание пихать кучу вызовов awk для обработки 5 строчек от ifconfig?

Вызовов минимум. AWK - это хороший специализированный язык, я его люблю, он красив.

Ведь так он и не научится программировать на bash

Он научился уже, вон nslookup | греп в цикле пускает для обработки строк в файле. Замечательно просто. Или нужен ещё и разбор выхлопа nslookup и route на чистом шелле? Оно конечно можно, но зачем?

временных файлов.

С файлами там прослеживается мысль. Пусть будут файлы.

legolegs ★★★★★ ()
Последнее исправление: legolegs (всего исправлений: 3)
Ответ на: комментарий от legolegs

AWK - это хороший специализированный язык, я его люблю, он красив.

Он красив именно потому, что это интерпретатор высокого уровня, со всеми вытекающими отсюда смешными моментами, когда его юзают только для вывода второго столбца второй строчки 7-ми строчного вывода... Меня он прежде всего бесит явным нежелание там было сделать обработку вывода запускаемой программы. Типа нефиг, тут вам не sh.

Он научился уже, вон nslookup | греп

Воот. Вместо того чтобы читать многострочный вывод и грепать, всего-то надо юзать неинтерактивную программу host через read без всякого цикла и грепа.

С файлами там прослеживается мысль. Пусть будут файлы.

Это чтобы вам было понятнее, а красота скрипта пофиг?

vodz ★★★★★ ()
Ответ на: комментарий от vodz

host

Он обрабатывает 1 имя за вызов, а у ТС дохрена имен, он же их автоматически генерит. Программа, работающая как фильтр тут уместнее.

Это чтобы вам было понятнее, а красота скрипта пофиг?

Не ожидал такого вопроса. Разумеется, понятность программы важнее красоты.

Убрать временные файлы, кончено, можно, но они здесь служат и для возможной отладки, и списки имён и адресов обновляются атомарно (в смысле не обрезаются в середине при сбое в скрипте).

legolegs ★★★★★ ()
Ответ на: комментарий от legolegs

Не ожидал такого вопроса.

А напрасно. ТС генерирует портянки без расписывания ТЗ, которое у него изначально не соотвествовало первому посту, а вы разбираете забесплатно эти портянки путем расчленения на что там во временных файлах и угадываете это ТЗ. И ещё удивляетесь, моему вопросу.

Разумеется, понятность программы важнее красоты.

Красота включает в себя понятность. Которая достигается комментариями, говорящими именами переменных, увеличением обозримости путём выкидывания создания и потом удаления временных файлов.

vodz ★★★★★ ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.