текстовый файл f.txt содержит ip адреса
192.168.100.120
172.31.25.12
Надо получить 2 массива
1 - содержит ip адреса
2 - содержит последние октеты ip адресовС первым массивом все понятно
open(FILE,f.txt)
while(<FILE>){
my ip_addr = $_;
}
print "@my_ipaddr\n" ;А вот как собрать массив 2 не понятно
Думаю надо читать строку с конца до символа точка
Подскажите плиз ! Я в Perl полный 0.
>собрать массив 2 не понятно
> Думаю надо читать строку с конца{
Начни с чтения какой ни то книжки про програмлянию. Для начала 10 подходов ао 2 часа. Много думать -- обязательно!Потом попробуй, следующие 10 подходов!, применить полученные к своему "читать строку с конца".
} Lather, rinse, repeat ()
>>собрать массив 2 не понятно
>> Думаю надо читать строку с конца
> {
> Начни с чтения какой ни то книжки про програмлянию. Для начала 10
> подходов ао 2 часа. Много думать -- обязательно!
> Потом попробуй, следующие 10 подходов!, применить полученные к своему "читать строку с
> конца".
> } Lather, rinse, repeat ()А может вот так
#!/usr/bin/perl -w
open(FILE,"f.txt");
while(<FILE>)
{
chomp;
my @ip_addr = $_;
print "@ip_addr\n" ;
foreach $arg (@ip_addr)
{
$x = rindex($arg,".");
my @ip_oktet = substr($arg,$x+1) ;
print "@ip_oktet\n" ;
}}
close(FILE);
>> Начни с чтения какой ни то книжки про програмлянию. Для начала 10
>> подходов ао 2 часа. Много думать -- обязательно!
> А может вот так
> ...Книжки всё-таки надо почитать. И думать, да. А потом уже кодить. Но тут-то делать особо нечего:
$ cat > ips
192.168.100.120
172.31.25.12
$ cat ips | perl -e 'while (<>) {chomp; push @ips, $_; s/.*\.//; push @last, $_;} $,="\n"; print "= ips =", @ips, "= last =", @last, "";'
= ips =
192.168.100.120
172.31.25.12
= last =
120
12
$ _
>[оверквотинг удален]
> $ cat ips | perl -e 'while (<>) {chomp; push @ips, $_;
> s/.*\.//; push @last, $_;} $,="\n"; print "= ips =", @ips, "=
> last =", @last, "";'
> = ips =
> 192.168.100.120
> 172.31.25.12
> = last =
> 120
> 12
> $ _
Согласен ! Так красивее и непонятнее
>[оверквотинг удален]
>> s/.*\.//; push @last, $_;} $,="\n"; print "= ips =", @ips, "=
>> last =", @last, "";'
>> = ips =
>> 192.168.100.120
>> 172.31.25.12
>> = last =
>> 120
>> 12
>> $ _
> Согласен ! Так красивее и непонятнееНу да, разумеется конструкции с rindex, substr и особенно print "@ip_addr\n" - это очень понятно и грамотно. Это сарказм, простите.
По существу же в вашем коде присутствуют фундаментальные ошибки:
my @ip_addr = $_;Тут вы, вероятно, хотите поместить значение в массив. На самом же деле вы на каждой итерации создаёте новый массив из одного (!) элемента. Именно из-за этого следующая строка выдаёт ожидаемый результат:
print "@ip_addr\n" ;Массив разворачивается в строку и выводится с переводом строки в конце. Но у вас цикл, а значит выводить на каждой итерации нужно не весь массив а отдельный элемент. Но, как замечено выше, у вас в массиве всегда только один элемент. Одна ошибка наложилась на другую, и чудесным образом получился нужный результат!
foreach $arg (@ip_addr)Вложенный цикл вообще непонятно зачем нужен. Во-первых, тело его всегда будет выполнено ровно один раз. Во-вторых, именно это вам и надо - один раз взять последний октет.
$x = rindex($arg,".");
my @ip_oktet = substr($arg,$x+1) ;А между тем есть замечательный механизм регулярных выражений, которым это действие выполняется проще и понятнее. И, опять же, массив здесь используется не к месту, как и выше.
В итоге задача не решена - хотя и получен внешне правильный вывод, но массивы-то не заполнены.
Теперь к "красивому и непонятному". Писалось в строку, чтобы не плодить лишних файлов. Пожертвуем "красотой" и прокомментируем:
while (<>) { # читаем стандартный ввод, пока там что-то есть
chomp; # обрезаем перевод строки
push @ips, $_; # помещаем прочитанный адрес в массив @ips
s/.*\.//; # удаляем всё, кроме последнего октета
push @last, $_; # а его помещаем в массив @last
}
$, = "\n"; # выводить будем каждую строку с новой строки
"= ips =",
@ips, # массив будет развёрнут в список и выведен поэлементно
"= last =",
@last, # то же
""; # это, чтобы вывести последний перевод строки