Форум программистов, компьютерный форум, киберфорум
Shell, Bash
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.83/6: Рейтинг темы: голосов - 6, средняя оценка - 4.83
0 / 0 / 0
Регистрация: 06.12.2018
Сообщений: 4
1

Добавление недостающих строк при сравнении двух файлов

06.12.2018, 10:14. Показов 1079. Ответов 11

Добрый день!

В postfix часто приходится вносить множество адресов для блокировки спама и прочей разной неведомой херни.
Есть 2 файла Source и Destination. В Source список адресов, которые УЖЕ блокируется или разрешается. В Destination - то что нужно заблокировать.

Пример Destination:
Код
kraftaudio.ru REJECT
foc-ug.ru REJECT
xxx.ru OK
sfdfsdf.com OK
146.34.121.15 REJECT
Пример Source:
Код
siet.com
foc-ug.ru
xxx.ru
10.10.10.20
Нужно сравнить эти файлы и добавить из Source в Destination то чего там нет. При этом логика такая:
если значение там есть, то ничего не добавлять.
если значение там "xxx.ru OK" то заменить его на "xxx.ru REJECT"
если значения там нет, то нужно его добавить в виде "адрес REJECT"

Добавлено через 55 минут
Вот такое пока что наваял.

Bash
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#!/bin/bash
Source_file=/home/user/source.file
Dest_file=/home/user/dest.file
 
IFS-$'\n'
set -f
 
for var in $(cat $Source_file)
do
      if grep -iq $var $Dest_file
then
      echo "$var already is in file!!"
else
      echo "$var REJECT will be added to $Dest_file"
fi
done
Добавлено через 11 минут
вот только не понятно как заменять одну переменную в цикле на другую((
__________________
Помощь в написании контрольных, курсовых и дипломных работ здесь
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
06.12.2018, 10:14
Ответы с готовыми решениями:

Не учитывается регистр при сравнении двух строк
Всех приветствую! Хотел узнать следующее: почему при следующем запросе SELECT * from users where...

Type mismatch при сравнении двух строк
Здравствуйте, уважаемые форумчане! При сравнении двух переменных : элемента коллекции типа строка ...

Зацикливание при сравнении строк
Добрый вечер. У меня возникла проблема при сравнивании строк, после сравнивания происходит расчет...

Ошибка при сравнении строк
Добрый день! Помогите, пожалуйста. Получаю версию операционной системы, и хочу чтобы вместо...

11
Модератор
Эксперт NIX
2787 / 2032 / 681
Регистрация: 02.03.2015
Сообщений: 6,509
06.12.2018, 12:19 2
Цитата Сообщение от isergwind Посмотреть сообщение
xxx.ru OK
Это только для одного файла менять ОК на REJECT?
0
4195 / 1569 / 269
Регистрация: 10.12.2013
Сообщений: 5,433
06.12.2018, 12:52 3
Если по-простому, без изысков

Bash
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#!/usr/bin/env perl -w
use strict;
 
open SRC, "Source.file"      or die $!;
open DST, "Destination.file" or die $!;
 
undef $/;
my @src = <SRC> =~ /\S+/mg;
my %dst = <DST> =~ /(\S+)\s+(REJECT|OK)/mgi;
 
close SRC;
close DST;
 
$dst{"\L$_"} = "REJECT" for @src;
 
open NEW, ">Destination.new" or die $!;
for ( sort keys %dst ) {
 
    printf NEW "%-20s %-s\n", $_, $dst{$_};
}    
 
 
print "Result in the file Destination.new\n";
1
0 / 0 / 0
Регистрация: 06.12.2018
Сообщений: 4
06.12.2018, 14:36  [ТС] 4
Цитата Сообщение от Marinero Посмотреть сообщение
Это только для одного файла менять ОК на REJECT?
Да, только для одного. А так файлов всего два. В Destination файле множество значений как с REJECT так и ОК.
В файле Source только строки c ip или доменами, без REJECT

Добавлено через 3 минуты
volodin661, Ойойой, perl. Не особо нем не понимаю, даже если потом захочу что-то подправить, то это будет проблема. А с башем нельзя такое? В любом случае спасибо!
0
4195 / 1569 / 269
Регистрация: 10.12.2013
Сообщений: 5,433
06.12.2018, 15:03 5
Цитата Сообщение от isergwind Посмотреть сообщение
Ойойой, perl. Не особо нем не понимаю
Но на bash ты тоже не смог выполнить задуманное, поэтому фактически разницы никакой.
0
Модератор
Эксперт NIX
2787 / 2032 / 681
Регистрация: 02.03.2015
Сообщений: 6,509
06.12.2018, 17:01 6
Цитата Сообщение от isergwind Посмотреть сообщение
с башем нельзя такое?
Можно. Самое простое: добавить в DEST строки из SOURCE с добавленным REJECT, отсортировать и удалить дубли. В итоге останутся первоначальные строки. Только плюсом сделать проверку на xxx.ru.
А так можно и Вашим способом:
Bash
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
while read var ; do
 
    if [ "$var" = "xxx.ru" ] ; then
        sed -i "/$var/s/OK/REJECT/" "$Dest_file"
        continue
    fi
 
    if grep -iqF "$var" "$Dest_file" ; then
        echo "$var already is in file!!"
    else
        echo "$var REJECT" >>"$Dest_file"
        echo "$var REJECT will be added to $Dest_file"
    fi
 
done <"$Source_file"
Добавлено через 33 минуты
Bash
1
2
3
4
5
if grep -iFq "xxx.ru" "$Source_file" ; then
    sed -i "/xxx.ru/s/OK/REJECT/" "$Dest_file"
fi
cat <"$Dest_file" <(sed 's/$/ REJECT/' "$Source_file") | sort -uk1,1 >"$Dest_file".new
mv "$Dest_file"{.new,}
0
0 / 0 / 0
Регистрация: 06.12.2018
Сообщений: 4
10.12.2018, 07:43  [ТС] 7
Цитата Сообщение от Marinero Посмотреть сообщение
Можно. Самое простое: добавить в DEST строки из SOURCE с добавленным REJECT, отсортировать и удалить дубли. В итоге останутся первоначальные строки. Только плюсом сделать проверку на xxx.ru.
Добрый день!
Отличная идея - добавить в Dest строки из Source с добавлением REGECT. А как тогда отсортировать дубли и удалить то, где встречается ОК ? В итоге в файле будут строки
yyy.ru OK
zzz.ru OK
xxx.ru OK
xxx.ru REGECT
То что не поменялось на REGECT должно остаться.

Дело в том, что подобных записей как xxx.ru OK там много и нет смысла грепать только одну строку "xxx.ru".
0
4195 / 1569 / 269
Регистрация: 10.12.2013
Сообщений: 5,433
10.12.2018, 08:42 8
все эти конфигурации, кстати, имеет смысл заправить в Makefile.
0
Модератор
Эксперт NIX
2787 / 2032 / 681
Регистрация: 02.03.2015
Сообщений: 6,509
10.12.2018, 10:47 9
Цитата Сообщение от isergwind Посмотреть сообщение
отсортировать дубли и удалить то, где встречается ОК
Bash
1
2
cat <(sed 's/$/ REJECT/' "$Source_file") <"$Dest_file" | sort -uk1,1 >"$Dest_file".new
mv -f "$Dest_file"{.new,}
Добавлено через 6 минут
Цитата Сообщение от isergwind Посмотреть сообщение
нет смысла грепать только одну строку "xxx.ru"
Можно наоборот:
Bash
1
2
3
grep -vFf "$Source_file" "$Dest_file" >"$Dest_file".new
sed 's/$/REJECT/'  "$Source_file" >>"$Dest_file".new
mv -f "$Dest_file"{.new,}
0
0 / 0 / 0
Регистрация: 06.12.2018
Сообщений: 4
11.12.2018, 08:54  [ТС] 10
volodin661, Добрый день! Подскажите пожалуйста, как изменить Ваш скрипт чтобы вывод был сразу в Destination.file а не в Destination.new ?

Идея-то здесь простая: сначала собрать в Source.file то что надо блокировать. Затем запустить скрипт, который добавит все значения в Destination.file.
0
4195 / 1569 / 269
Регистрация: 10.12.2013
Сообщений: 5,433
11.12.2018, 11:13 11
Цитата Сообщение от isergwind Посмотреть сообщение
как изменить Ваш скрипт чтобы вывод был сразу в Destination.file а не в Destination.new ?
Заменить в строке 16 слова

">Destination.new"

на

">Destination.file"
0
188 / 145 / 32
Регистрация: 04.10.2013
Сообщений: 149
12.12.2018, 11:33 12
Цитата Сообщение от isergwind Посмотреть сообщение
если значение там есть, то ничего не добавлять.
ничего не выполнять
Цитата Сообщение от isergwind Посмотреть сообщение
если значение там "xxx.ru OK" то заменить его на "xxx.ru REJECT"
Bash
1
grep -F "$(grep OK sour-dest/Destination |cut -d' ' -f1 )" sour-dest/Source |xargs -Iarg sed -i 's/arg.*/arg REJECT/g' sour-dest/Destination
Цитата Сообщение от isergwind Посмотреть сообщение
если значения там нет, то нужно его добавить в виде "адрес REJECT"
Bash
1
grep -vF "$(cut -d' ' -f1 sour-dest/Destination)" sour-dest/Source |xargs -Iarg echo arg REJECT >> sour-dest/Destination
0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
12.12.2018, 11:33

Кодировка при сравнении строк
Всем привет! Про кодировки читал много на вашем форуме, однако применить к своей задаче так и не...

Ошибка при сравнении строк
Привет всем! Задача стояла такая, написать программу, которая бы три раза спрашивала пароль, и...

Найти ошибку при сравнении файлов
Помогите,пожалуйста найти ошибку. По заданию надо описать логическую функцию eq(f,q),проверяющая на...

Игнорировать регистр при сравнении строк
Как сделать так, чтобы программа не обращала внимания на регистр. Например я пишу: if...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
12
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2022, CyberForum.ru