URL: https://www.opennet.me/cgi-bin/openforum/vsluhboard.cgi
Форум: vsluhforumID9
Нить номер: 9597
[ Назад ]

Исходное сообщение
"Удаление строк"

Отправлено romiks , 10-Дек-12 11:28 
Всем здравствовать!

Есть 1 файл. Со строками.
В каждой строке есть бла-бла-бла IP-адрес бла-бла-бла.
То есть текст и в нём IP-адрес.
Есть 2 файл. Чисто с одними IP-адресами.

Нужно удалить из файла 1 все строки,
в которых встречаются ip из файла 2.

@f2 = <FILE2>;
foreach $str2 (@f2) {
    chomp $str2;
    while ($str1 = <FILE1>) {
        $str1 =~ m/(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})/g;
        if ( $1 ne $str2) {
            print $str1;
        }
    }
}

Запутался я с этими циклами.
Не получается. Удаляет только одну строку из файла 1,
в которой есть первый ip из файла 2.
Подскажите?


Содержание

Сообщения в этом обсуждении
"Удаление строк"
Отправлено Dno , 10-Дек-12 12:30 
А grep использовать не судьба (grep -vf ..)?

"Удаление строк"
Отправлено romiks , 10-Дек-12 12:48 
> А grep использовать не судьба (grep -vf ..)?

Да и на sed можно (sed -i '' /ip/d)
Но нужно на perl


"Удаление строк"
Отправлено qqq , 10-Дек-12 12:46 
> Всем здравствовать!
> Есть 1 файл. Со строками.
> В каждой строке есть бла-бла-бла IP-адрес бла-бла-бла.
> То есть текст и в нём IP-адрес.
> Есть 2 файл. Чисто с одними IP-адресами.
> Нужно удалить из файла 1 все строки,
> в которых встречаются ip из файла 2.

for a in `cat /path/to/file2`; do sed -i -e "/$a/d" path/to/file1; done


"Удаление строк"
Отправлено romiks , 10-Дек-12 12:57 
>> Всем здравствовать!
>> Есть 1 файл. Со строками.
>> В каждой строке есть бла-бла-бла IP-адрес бла-бла-бла.
>> То есть текст и в нём IP-адрес.
>> Есть 2 файл. Чисто с одними IP-адресами.
>> Нужно удалить из файла 1 все строки,
>> в которых встречаются ip из файла 2.
> for a in `cat /path/to/file2`; do sed -i -e "/$a/d" path/to/file1; done

Да, пробовал уже, аналогично.
Проблема вылазит, в шеловском скрипте удаляет, скажем, кроме 192.168.1.3
и ещё кучу таких как 192.168.1.32, 192.168.1.39 и иже с ним.
как указать sed'у конец строки?
/^ip$/d не проходит, не понимает он конец строки $ (не понимает имеенно в sh скрипте)


"Удаление строк"
Отправлено qqq , 10-Дек-12 13:20 
> Проблема вылазит, в шеловском скрипте удаляет, скажем, кроме 192.168.1.3
> и ещё кучу таких как 192.168.1.32, 192.168.1.39 и иже с ним.
> как указать sed'у конец строки?
> /^ip$/d не проходит, не понимает он конец строки $ (не понимает имеенно
> в sh скрипте)

нужно экранирование, т.е.

for a in `cat /path/to/file2`; do sed -i -e "/$a\$/d" path/to/file1; done

если IP действительно стоит в конце строки. Зачастую перед "концом" стоки еще стоит пробел, и тогда регэксп не отработает, следует видоизменить на "/$a /d".

Ну или у вас могут быть какие-то другие характерные признаки, если IP стоит в тексте между другими словами/символами, тогда добавьте два пробела "/ $a /d". В общем, экспериментируйте.


"Удаление строк"
Отправлено romiks , 10-Дек-12 14:40 
>[оверквотинг удален]
>> /^ip$/d не проходит, не понимает он конец строки $ (не понимает имеенно
>> в sh скрипте)
> нужно экранирование, т.е.
> for a in `cat /path/to/file2`; do sed -i -e "/$a\$/d" path/to/file1; done
> если IP действительно стоит в конце строки. Зачастую перед "концом" стоки еще
> стоит пробел, и тогда регэксп не отработает, следует видоизменить на "/$a
> /d".
> Ну или у вас могут быть какие-то другие характерные признаки, если IP
> стоит в тексте между другими словами/символами, тогда добавьте два пробела "/
> $a /d". В общем, экспериментируйте.

А вы сами пробовали с экранированием?
Я - да, не помогает. Причём, в различных вариациях.
И с двумя кавычками, и с одной. Результат один.

Потому как у sed'а своё "понимание" $(конец строки) ,
а у sh - своё (переменная)


cat file1
text1 192.168.1.1 text
text2 192.168.2.1 text
text2 192.168.2.11 text
text3 192.168.3.1 text


cat file2
192.168.2.1


cat test.sh

/bin/sh
ip="file2"
for i in $(cat ${ip}); do
    sed -i '' /$i/d file1
done

sed -i "" /$i/d file1
sed -i "" /$i$/d file1
sed -i "" '/$i$/d' file1
sed -i "" "/$i$/d" file1
Безрезультатно. И если заслешивать конец строки - то есть \$
А вот с пробелами - работает.
Или с дополнительным символом в конце ip адреса,
например если file1 имеет вид

text1 192.168.1.1; text
text2 192.168.2.1; text
text2 192.168.2.11; text
text3 192.168.3.1; text

тогда - да так работает - sed -i "" /$i\;/d file1
Спасибо за помощь!


"Удаление строк"
Отправлено qqq , 10-Дек-12 14:50 
>[оверквотинг удален]
> Я - да, не помогает. Причём, в различных вариациях.
> И с двумя кавычками, и с одной. Результат один.
> Потому как у sed'а своё "понимание" $(конец строки) ,
> а у sh - своё (переменная)
>
 
> cat file1
> text1 192.168.1.1 text
> text2 192.168.2.1 text
> text2 192.168.2.11 text
> text3 192.168.3.1 text

а вот скажите, пожалуйста, с какого это бы седу удалять по регэкспу $ip\$ (ip адрес+конец строки), если у вас ip находится в *середине* строки? откуда взяться символу конца строки посреди стоки?


"Удаление строк"
Отправлено romiks , 10-Дек-12 15:32 
> а вот скажите, пожалуйста, с какого это бы седу удалять по регэкспу
> $ip\$ (ip адрес+конец строки), если у вас ip находится в *середине*
> строки? откуда взяться символу конца строки посреди стоки?

Согласен! Косяк мой. Не туда смотрел, блин.
Всё работает.

text1 192.168.1.1
text2 192.168.2.1
text2 192.168.2.11
text3 192.168.3.1

sed -i "" "/$i$/d" file1

text1 192.168.1.1
text2 192.168.2.11
text3 192.168.3.1

Простите меня! )))


"Удаление строк"
Отправлено XAnder , 10-Дек-12 14:03 
> Есть 1 файл. Со строками.
> В каждой строке есть бла-бла-бла IP-адрес бла-бла-бла.
> То есть текст и в нём IP-адрес.
> Есть 2 файл. Чисто с одними IP-адресами.
> Нужно удалить из файла 1 все строки,
> в которых встречаются ip из файла 2.

my %ips = ();
open FH, 'file2';
while (<FH>) {
    chomp;
    $ips{$_} = 1;
}
close FH;

open FH, 'file1';
while (<FH>) {
    next unless m/\b(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})\b/;
    print $_ unless exists $ips{$1};
}
close FH;

Идея с хешем, думаю, понятна.

PS. На работоспособность не проверял, если что.


"Удаление строк"
Отправлено romiks , 10-Дек-12 15:21 
>[оверквотинг удален]
> }
> close FH;
> open FH, 'file1';
> while (<FH>) {
>  next unless m/\b(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})\b/;
>  print $_ unless exists $ips{$1};
> }
> close FH;

> Идея с хешем, думаю, понятна.
> PS. На работоспособность не проверял, если что.

Да! Работает! Спасибо!