Всем здравствовать!Есть 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.
Подскажите?
А grep использовать не судьба (grep -vf ..)?
> А grep использовать не судьба (grep -vf ..)?Да и на sed можно (sed -i '' /ip/d)
Но нужно на perl
> Всем здравствовать!
> Есть 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
>> Всем здравствовать!
>> Есть 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 скрипте)
> Проблема вылазит, в шеловском скрипте удаляет, скажем, кроме 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". В общем, экспериментируйте.
>[оверквотинг удален]
>> /^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
donesed -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
Спасибо за помощь!
>[оверквотинг удален]
> Я - да, не помогает. Причём, в различных вариациях.
> И с двумя кавычками, и с одной. Результат один.
> Потому как у 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 находится в *середине* строки? откуда взяться символу конца строки посреди стоки?
> а вот скажите, пожалуйста, с какого это бы седу удалять по регэкспу
> $ip\$ (ip адрес+конец строки), если у вас ip находится в *середине*
> строки? откуда взяться символу конца строки посреди стоки?Согласен! Косяк мой. Не туда смотрел, блин.
Всё работает.text1 192.168.1.1
text2 192.168.2.1
text2 192.168.2.11
text3 192.168.3.1sed -i "" "/$i$/d" file1
text1 192.168.1.1
text2 192.168.2.11
text3 192.168.3.1Простите меня! )))
> Есть 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. На работоспособность не проверял, если что.
>[оверквотинг удален]
> }
> 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;
Да! Работает! Спасибо!