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 не нужон строчкой)

★★

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

-=:=-

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

KosmiK ★★
() автор топика

-=:=-

echo "33355f354f2345.f345f2345f3.2345fd2345f3.2345f2345f.2345f3245.344" | cut -d'.' -f2-


А вот как это в цикл поставить...

KosmiK ★★
() автор топика
Последнее исправление: KosmiK (всего исправлений: 2)
<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

Микротыков много. Да и нагрузка бывает разная. Но на него 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)
Ответ на: комментарий от anonymous

И что? То, что моя грепалка рандома такие не выдаёт на работоспособности скриптов не сказывается.

legolegs ★★★★★
()
Ответ на: комментарий от 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 ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.