На самом деле это единственный раздел про unix на этом форуме
Модераторы: /dev/random , Модераторы разделов
gunb1rd
Сообщения: 5
Сообщение
gunb1rd » 01.02.2014 00:11
Доброй ночи, друзья! Прошу совета. Имеется такой текст:
Код: Выделить всё
ch1:512
ch2:2048
ch3:1024
ch4:2048
ch5:4096
ch1:192.95.52.1
ch3:172.94.51.0
ch5:8.8.8.8
Это channel, speed и ip, необходимо добавить ip к speed, в строке у которой, такойже channel. Чтобы получилось вот так:
Код: Выделить всё
ch1:512:192.95.52.1
ch3:1024:172.94.51.0
ch5:4096:8.8.8.8
За ранее благодарю за помощь!
/dev/random
Администратор
Сообщения: 5282
ОС: Gentoo
Сообщение
/dev/random » 01.02.2014 00:26
join -t : <(grep -v '[.]' in.txt) <(grep '[.]' in.txt)
Используется bash-специфичная конструкция, для других шеллов нужно переделывать.
gunb1rd
Сообщения: 5
Сообщение
gunb1rd » 01.02.2014 01:08
Почемуто не все файлы обрабатывает как надо. Допустим файл ./146 обработало не до конца
Код: Выделить всё
[freebsd]$ cat 146
ch1:6144
ch3:2048
ch4:2048
ch7:1024
ch8:1024
ch9:5120
ch10:512
ch11:2048
ch12:2048
ch13:5120
ch14:5120
ch1:1.1.1.1
ch3:1.1.1.1
ch7:2.2.2.2
ch11:3.3.3.3
ch13:4.4.4.4
[freebsd]$ join -t : <(grep -v '[.]' ./146) <(grep '[.]' ./146)
ch1:6144:1.1.1.1
ch3:2048:1.1.1.1
ch7:1024:2.2.2.2
а файл ./156 обработало как надо. вроде бы различий в файле нет никаких, не подскажете, в чём проблема?
Код: Выделить всё
[freebsd]$ cat 156
ch1:3072
ch3:1024
ch4:1024
ch5:2048
ch6:2048
ch9:3072
ch10:512
ch11:3072
ch12:3072
ch13:3072
ch14:3072
ch1:1.1.1.1
ch3:2.2.2.2
ch5:2.2.2.2
ch9:4.4.4.4
ch11:5.5.5.5
ch13:6.6.6.6
[freebsd]$ join -t : <(grep -v '[.]' ./156) <(grep '[.]' ./156)
ch1:3072:1.1.1.1
ch3:1024:2.2.2.2
ch5:2048:2.2.2.2
ch9:3072:4.4.4.4
ch11:3072:5.5.5.5
ch13:3072:6.6.6.6
/dev/random
Администратор
Сообщения: 5282
ОС: Gentoo
Сообщение
/dev/random » 01.02.2014 01:18
join'у требуется алфавитная сортировка, а в ваших файлах - числовая. Из первого примера этого не было видно, так что не сообразил.
Тогда так:
join -t : <(grep -v '[.]' in.txt | sort -t : -k 1,1) <(grep '[.]' in.txt | sort -t : -k 1,1)
gunb1rd
Сообщения: 5
Сообщение
gunb1rd » 01.02.2014 01:36
Спасибо огромное! Всё спарсил
Правда я пока не знаю почему и как это работает, но обещаю в скором времени разобраться =) С bash только начал знакомтсво.
Ещё раз спасибо!
gunb1rd
Сообщения: 5
Сообщение
gunb1rd » 01.02.2014 12:11
будте добры, подскажите ещё, как слить 2 списка:
file1:
Код: Выделить всё
name1:192.168.0.1/29
name2:172.13.15.16/32
name3:192.168.0.2/32
name4:172.13.15.17/30
name5:192.168.0.3/28
name6:172.13.15.18/32
file2:
Код: Выделить всё
ch1:12288:192.168.0.1
ch11:2048:192.168.0.2
ch13:512:192.168.0.3
Чтобы на выходе получить только то что в file2 + name из file1, ip которых равны
file3
Код: Выделить всё
ch1:12288:192.168.0.1:name1
ch11:2048:192.168.0.2:name3
ch13:512:192.168.0.3:name5
За ранее спасибо
SLEDopit
Модератор
Сообщения: 4823
Статус: фанат консоли (=
ОС: GNU/Debian, RHEL
Сообщение
SLEDopit » 01.02.2014 12:53
gunb1rd писал(а): ↑ 01.02.2014 01:36
Правда я пока не знаю почему и как это работает
/dev/random писал(а): ↑ 01.02.2014 01:18
join -t : <(grep -v '[.]' in.txt | sort -t : -k 1,1) <(grep '[.]' in.txt | sort -t : -k 1,1)
join -- объединяет файлы по общему полю
-t : -- в качестве разделитя использовать :
<() -- подробно про такую штуку можно почитать
тут
grep -v '[.]' in.txt | sort -t : -k 1,1 -- вывести файл в stdout, удалив все строки с точкой и отсортировать , использую разделитель поля :
По вашей второй просьбе будет примерно так:
Код: Выделить всё
join -t : -1 2 -2 3 <(sort -k1 -t: 1 | sed 's=/.*==') <(sort -k3 -t: 2)
Попробуйте разобраться самостоятельно, как это работает
UNIX is basically a simple operating system, but you have to be a genius to understand the simplicity. © Dennis Ritchie
The more you believe you don't do mistakes, the more bugs are in your code.
/dev/random
Администратор
Сообщения: 5282
ОС: Gentoo
Сообщение
/dev/random » 01.02.2014 13:03
SLEDopit писал(а): ↑ 01.02.2014 12:53
Код: Выделить всё
join -t : -1 2 -2 3 <(sort -k1 -t: 1 | sed 's=/.*==') <(sort -k3 -t: 2)
Я бы всё-таки рекомендовал для sort задавать и начальное, и конечное поле, так как join ожидает сортировку по одному полю, а не по всем, начиная с указанного. Т.е. не "-k1", а "-k1,1".
gunb1rd
Сообщения: 5
Сообщение
gunb1rd » 01.02.2014 13:35
Спасибо. Постараюсь разобраться.
Код: Выделить всё
join -t : -1 2 -2 3 <(sort -k1,1 -t: ips.lst | sed 's=/.*==') <(sort -k1,1 -t: name.lst)
не работает. выдаёт тот же список name.lst только с : в начале строки
/dev/random
Администратор
Сообщения: 5282
ОС: Gentoo
Сообщение
/dev/random » 01.02.2014 13:46
gunb1rd писал(а): ↑ 01.02.2014 13:35
Спасибо. Постараюсь разобраться.
Код: Выделить всё
join -t : -1 2 -2 3 <(sort -k1,1 -t: ips.lst | sed 's=/.*==') <(sort -k1,1 -t: name.lst)
не работает. выдаёт тот же список name.lst только с : в начале строки
join -t : -1 2 -2 3 <(sort -k2,2 -t: name.lst | sed 's=/.*==') <(sort -k3,3 -t: ips.lst)
Или, если важен именно такой порядок полей, как в образце (join по умолчанию ставит общее поле в начало), то так:
join -t : -1 2 -2 3 <(sort -k2,2 -t: name.lst | sed 's=/.*==') <(sort -k3,3 -t: ips.lst) -o 2.1,2.2,0,1.1
drBatty
Сообщения: 8735
Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
ОС: Slackware-current
Контактная информация:
Сообщение
drBatty » 02.02.2014 13:03
gunb1rd
я хотел дать sed-скрипт, но подумав решил, что гвозди лучше забивать молотком, а сливать строки join'ом.