awk. Замена поля
Убедительная просьба юзать теги [code] при оформлении листингов.
Сообщения не оформленные должным образом имеют все шансы быть незамеченными.
-
- сержант
- Сообщения: 169
- Зарегистрирован: 2008-04-05 20:09:45
- Откуда: Киев
awk. Замена поля
Необходимо в файле file в строке содержащей вхождение free заменить второе поле. Пишу:
awk "/free/ {sub(/$2/,\"some text\");print}" file
Но some text добавляется в начало строки, втрое поле остается.
Как правильно?
Услуги хостинговой компании Host-Food.ru
Тарифы на виртуальные сервера (VPS/VDS/KVM) в РФ, от 189 руб.: https://www.host-food.ru/tariffs/virtualny-server-vps/
Выделенные сервера, Россия, Москва, от 2000 рублей (HP Proliant G5, Intel Xeon E5430 (2.66GHz, Quad-Core, 12Mb), 8Gb RAM, 2x300Gb SAS HDD, P400i, 512Mb, BBU):
https://www.host-food.ru/tariffs/vydelennyi-server-ds/
Недорогие домены в популярных зонах: https://www.host-food.ru/domains/
-
- проходил мимо
Re: awk. Замена поля
заменить foo на bar в втором поле - sub("foo", "bar", $2)Termitnik писал(а):awk "/free/ {sub(/$2/,\"some text\");print}" file
-
- полковник
- Сообщения: 5845
- Зарегистрирован: 2007-12-07 13:51:33
- Откуда: Верх-Нейвинск
Re: awk. Замена поля
-
- сержант
- Сообщения: 169
- Зарегистрирован: 2008-04-05 20:09:45
- Откуда: Киев
Re: awk. Замена поля
Содержимое втрого поля может варьироваться, мне нужно заменить его целиком.Гость писал(а):заменить foo на bar в втором поле - sub("foo", "bar", $2)Termitnik писал(а):awk "/free/ {sub(/$2/,\"some text\");print}" file
Есть:zg писал(а):образец дай, чего есть, чего надо, а там видно будет, чего и как заменять
vlan31 ХХХ.ХХХ.ХХХ.ХХХ/ХХ free
Надо:
vlan31 YYY.YYY.YYY.YYY/YY free
-
- полковник
- Сообщения: 5845
- Зарегистрирован: 2007-12-07 13:51:33
- Откуда: Верх-Нейвинск
Re: awk. Замена поля
Код: Выделить всё
zg# awk '{if ($1=="vlan31") $2="YYY.YYY.YYY.YYY/YY"; print}' 1.txt
vlan31 YYY.YYY.YYY.YYY/YY free
inet XXX.XXX.XXX.XXX netmask XXX.XXX.XXX.XXX
zg# cat 1.txt
vlan31 ХХХ.ХХХ.ХХХ.ХХХ/ХХ free
inet XXX.XXX.XXX.XXX netmask XXX.XXX.XXX.XXX
zg#
Код: Выделить всё
zg# awk '{if (match($0, "free")) $2="YYY.YYY.YYY.YYY/YY"; print}' 1.txt
vlan31 YYY.YYY.YYY.YYY/YY free
inet XXX.XXX.XXX.XXX netmask XXX.XXX.XXX.XXX
zg#
-
- сержант
- Сообщения: 169
- Зарегистрирован: 2008-04-05 20:09:45
- Откуда: Киев
Re: awk. Замена поля
-
- проходил мимо
- Сообщения: 2
- Зарегистрирован: 2009-04-13 16:24:37
Re: awk. Замена поля
Есть аналогичная задача, пытаюсь применить приведенный здесь скрипт, но не срабатывает.
Есть много файлов с именами в формате ГГММДДЧЧ.* примерно такого формата:
Код: Выделить всё
030209 1156 00011 9 9 717 8962XXXXABCD 702 05 35 702 702 4 0 2
030209 1156 00025 9 333 06 702 702 0 0 2
030209 1156 00019 7 9 714 ZZZZZZZ 333 11 333 4 0 1
030209 1156 00038 9 9 717 8926XXXXXXXX ZZZZZZZ 26 15 714 ZZZZZZZ 4 0 2
Скрипт выглядит таким образом:
Код: Выделить всё
awk '{match($7, "8962XXXXABCD") $8="030"; print}' 0903*
awk '{match($7, "8962XXXXABCD") $12="030"; print}' 0903*
Так тоже пробовал, с таким же результатом:
Код: Выделить всё
awk '{if ($7=="8962XXXXABCD") $8="030"; print}' 0903*
awk '{if ($7=="8962XXXXABCD") $12="030"; print}' 0903*
Подскажите, как можно с этим справиться? Куда посмотреть?
-
- полковник
- Сообщения: 5845
- Зарегистрирован: 2007-12-07 13:51:33
- Откуда: Верх-Нейвинск
Re: awk. Замена поля
-))) и не будет, пока вывод не завернёшь куда надоzrad писал(а):Но после запуска скрипта никаких изменений в файлах не наблюдается.
-
- проходил мимо
- Сообщения: 2
- Зарегистрирован: 2009-04-13 16:24:37
Re: awk. Замена поля
А есть способ сделать так, чтобы изменения происходили во входных файлах? Ну или чтобы на выходе сгенерировались копии этих файлов с идентичными именами и полным содержимым с отличием только в точках замен?
-
- полковник
- Сообщения: 5845
- Зарегистрирован: 2007-12-07 13:51:33
- Откуда: Верх-Нейвинск
Re: awk. Замена поля
через временные файлыzrad писал(а):А есть способ сделать так, чтобы изменения происходили во входных файлах?
Код: Выделить всё
cat some.file | обработка > tmp.file
mv tmp.file some.file
-
- прапорщик
- Сообщения: 496
- Зарегистрирован: 2015-05-25 14:36:32
awk. Замена поля
Не факт, что это нельзя было сделать короче.
Уперся я в сортировку с датами в ком. строке шелла csh.
Есть, допустим, два файла, первый: cat file3
Код: Выделить всё
Apr 01 00:00:00 [чего-то там 1]
Apr 9 08:50:48 [чего-то там 8]
Apr 8 09:20:37 [чего-то там 3]
Apr 8 22:22:40 [чего-то там 4]
Apr 22 22:26:41 [чего-то там 225]
Apr 18 22:26:41 [чего-то там 25]
Apr 8 22:26:41 [чего-то там 5]
Apr 8 22:27:56 [чего-то там 6]
Apr 8 23:27:27 [чего-то там 7]
Apr 3 08:59:28 [чего-то там 2]
Код: Выделить всё
08-Apr-2017 22:21:51 [чего-то там 10]
08-Apr-2017 22:27:57 [чего-то там 16]
08-Apr-2017 22:23:53 [чего-то там 12]
08-Apr-2017 22:24:54 [чего-то там 13]
18-Apr-2017 22:24:56 [чего-то там 2213]
18-Apr-2017 22:24:54 [чего-то там 213]
19-Apr-2017 22:24:54 [чего-то там 213]
08-Apr-2017 22:25:55 [чего-то там 14]
08-Apr-2017 22:26:56 [чего-то там 15]
08-Apr-2017 22:22:52 [чего-то там 11]
Вариант cat file3 file4|sort -g дает нам:
Код: Выделить всё
Apr 01 00:00:00 [чего-то там 1]
Apr 18 22:26:41 [чего-то там 25]
Apr 22 22:26:41 [чего-то там 225]
Apr 3 08:59:28 [чего-то там 2]
Apr 8 09:20:37 [чего-то там 3]
Apr 8 22:22:40 [чего-то там 4]
Apr 8 22:26:41 [чего-то там 5]
Apr 8 22:27:56 [чего-то там 6]
Apr 8 23:27:27 [чего-то там 7]
Apr 9 08:50:48 [чего-то там 8]
08-Apr-2017 22:21:51 [чего-то там 10]
08-Apr-2017 22:22:52 [чего-то там 11]
08-Apr-2017 22:23:53 [чего-то там 12]
08-Apr-2017 22:24:54 [чего-то там 13]
08-Apr-2017 22:25:55 [чего-то там 14]
08-Apr-2017 22:26:56 [чего-то там 15]
08-Apr-2017 22:27:57 [чего-то там 16]
18-Apr-2017 22:24:54 [чего-то там 213]
18-Apr-2017 22:24:56 [чего-то там 2213]
19-Apr-2017 22:24:54 [чего-то там 213]
Код: Выделить всё
Apr 01 00:00:00 [чего-то там 1]
Apr 3 08:59:28 [чего-то там 2]
Apr 8 09:20:37 [чего-то там 3]
Apr 8 22:22:40 [чего-то там 4]
Apr 8 22:26:41 [чего-то там 5]
Apr 8 22:27:56 [чего-то там 6]
Apr 8 23:27:27 [чего-то там 7]
Apr 9 08:50:48 [чего-то там 8]
Apr 18 22:26:41 [чего-то там 25]
08-Apr-2017 22:21:51 [чего-то там 10]
08-Apr-2017 22:22:52 [чего-то там 11]
08-Apr-2017 22:23:53 [чего-то там 12]
08-Apr-2017 22:24:54 [чего-то там 13]
08-Apr-2017 22:25:55 [чего-то там 14]
08-Apr-2017 22:26:56 [чего-то там 15]
08-Apr-2017 22:27:57 [чего-то там 16]
18-Apr-2017 22:24:54 [чего-то там 213]
18-Apr-2017 22:24:56 [чего-то там 2213]
19-Apr-2017 22:24:54 [чего-то там 213]
Apr 22 22:26:41 [чего-то там 225]
Решение нашел такое (в одну строку):
Код: Выделить всё
# ( ( cat file3 | awk '{ print $2 "-" $1 "-2017 " $3 " - " $0}' | sort ) && ( cat file4 | sort ) ) | awk '{first=substr($0,1,1);gsub("0","",first);end=substr($0,2);print first end}' | sort -g
Код: Выделить всё
1-Apr-2017 00:00:00 - Apr 01 00:00:00 [чего-то там 1]
3-Apr-2017 08:59:28 - Apr 3 08:59:28 [чего-то там 2]
8-Apr-2017 09:20:37 - Apr 8 09:20:37 [чего-то там 3]
8-Apr-2017 22:21:51 [чего-то там 10]
8-Apr-2017 22:22:40 - Apr 8 22:22:40 [чего-то там 4]
8-Apr-2017 22:22:52 [чего-то там 11]
8-Apr-2017 22:23:53 [чего-то там 12]
8-Apr-2017 22:24:54 [чего-то там 13]
8-Apr-2017 22:25:55 [чего-то там 14]
8-Apr-2017 22:26:41 - Apr 8 22:26:41 [чего-то там 5]
8-Apr-2017 22:26:56 [чего-то там 15]
8-Apr-2017 22:27:56 - Apr 8 22:27:56 [чего-то там 6]
8-Apr-2017 22:27:57 [чего-то там 16]
8-Apr-2017 23:27:27 - Apr 8 23:27:27 [чего-то там 7]
9-Apr-2017 08:50:48 - Apr 9 08:50:48 [чего-то там 8]
18-Apr-2017 22:24:54 [чего-то там 213]
18-Apr-2017 22:24:56 [чего-то там 2213]
18-Apr-2017 22:26:41 - Apr 18 22:26:41 [чего-то там 25]
19-Apr-2017 22:24:54 [чего-то там 213]
22-Apr-2017 22:26:41 - Apr 22 22:26:41 [чего-то там 225]
- Alex Keda
- стреляли...
- Сообщения: 35456
- Зарегистрирован: 2004-10-18 14:25:19
- Откуда: Made in USSR
- Контактная информация:
awk. Замена поля
тока месяц должен быть числовой
и сортировать по человечески ...
-
- прапорщик
- Сообщения: 496
- Зарегистрирован: 2015-05-25 14:36:32
awk. Замена поля
Месяц прописью из лога.Alex Keda писал(а):таки год в начало, месяц, потом дату
тока месяц должен быть числовой
и сортировать по человечески ...
Понятно, что можно преобразование наворотить, но это как-то совсем наворочено будет...
И еще на заметку, в памятку...
Озадачился, тут намедни, фильтрацией данных в командной строке.
Суть вопроса в чем?
Есть некий текстовый файл с данными.
"Хочу посчитать количество встречающихся известных цифирь."
Звучит вроде просто.
Но, что я получаю...
Меня удручает:
Код: Выделить всё
cat 2017-10-31_full.txt | grep ", 307"
odlkmax_23679_1509170974.418754, 307
odlkmax_17245_1509210784.571775, 307
odlkmax_17332_1509210793.818450, 307
odlkmax_29899_1509221316.862000, 307
odlkmax_3904_1509226874.866412, 307
odlkmax_31238_1508403581.170446, 655, 307
odlkmax_5509_1509256589.421416, 307
Код: Выделить всё
cat 2017-10-31_full.txt | grep ", 30"
odlkmax_23679_1509170974.418754, 307
odlkmin_29851_1508380755.414015, 30
odlkmax_17245_1509210784.571775, 307
odlkmax_17332_1509210793.818450, 307
odlkmax_29899_1509221316.862000, 307
odlkmax_3904_1509226874.866412, 307
odlkmax_31238_1508403581.170446, 655, 307
odlkmax_5509_1509256589.421416, 307
Понятное дело, что если так:
Код: Выделить всё
cat 2017-10-31_full.txt | grep ", 3"
Пробовал конструкцию вида:
Код: Выделить всё
cat 2017-10-31_full.txt | grep ", 307" | awk '$2 == 307,$3 == 307'
odlkmax_23679_1509170974.418754, 307
odlkmax_17245_1509210784.571775, 307
odlkmax_17332_1509210793.818450, 307
odlkmax_29899_1509221316.862000, 307
odlkmax_3904_1509226874.866412, 307
odlkmax_31238_1508403581.170446, 655, 307
odlkmax_5509_1509256589.421416, 307
но в ней тоже есть "подводный камень".
Который заключается в том, что ", 655, 307" могут быть произвольными в своем порядке.
Т.е.
Код: Выделить всё
", 655, 307",
", 655, 307, 3030"
", 655, 455, 725, 836, 307"
Код: Выделить всё
cat 2017-10-31_full.txt | grep ", 307" | awk '$2 == 307,$3 == 307'
cat 2017-10-31_full.txt | grep ", 307" | awk '$2 == 307,$3 == 307,$4 == 307'
cat 2017-10-31_full.txt | grep ", 307" | awk '$2 == 307,$3 == 307,$4 == 307,$5 == 307'
А хочется получить именно все содержащие "307-ые" или все "30-ые" строки.
Пробовал такой вариант:
Код: Выделить всё
cat 2017-10-31_full.txt | grep ", 307" | awk 'match($0,/307/) {START2 = index($0,"307");print
307
307
307
307
307
307
307
Ближе всех такой вариант:
Код: Выделить всё
cat 2017-10-31_full.txt | awk '{for(i=1;i<=NF;i++){ if($i=="307"){print $i} } }'
307
307
307
307
307
307
307
или так
Код: Выделить всё
cat 2017-10-31_full.txt | awk '{for(i=1;i<=NF;i++){ if($i=="30"){print $i} } }'
30
Но абсолютно не верно если условие достигает 3 (тройки).
Код: Выделить всё
cat 2017-10-31_full.txt | awk '{for(i=1;i<=NF;i++){ if($i=="3"){print $i} } }'
Что их отделить нужно фильтровать по ", 3",
но эти значения в i не подставишь, что логично.
Пробовал еще такие варианты:
Код: Выделить всё
cat 2017-10-31_full.txt | grep ", 307" | awk '{for(i=1;i<=NF;i++){ if($i=="307"){print $i} } }'
307
307
307
307
307
307
307
Код: Выделить всё
cat 2017-10-31_full.txt | grep ", 30" | awk '{for(i=1;i<=NF;i++){ if($i=="30"){print $i} } }'
30
Код: Выделить всё
cat 2017-10-31_full.txt | grep ", 3" | awk '{for(i=1;i<=NF;i++){ if($i=="3"){print $i} } }'
Понятно, что само значение "3" это подставляется в виде переменной в скрипте.
Но, сначала, оное должно отработать в CLI.
Было подсказано, грамотным человеком, искать в направлении использования конструкции на sed (sed -n '/.*7.*/p')
Попробован пример для 7-ки.
Код: Выделить всё
cat 2017-06-30_full.txt | grep ", 7" | sed -n '/.*7.*/p'
odlk3_7515_1498741105.011651, 7, 270
odlk3_31868_1498237437.342564, 35, 7
odlk3_19163_1498768687.158794, 717
Но для меня такая строка "лишняя".
Правильный результат должен был быть как:
Код: Выделить всё
odlk3_7515_1498741105.011651, 7, 270
odlk3_31868_1498237437.342564, 35, 7
Но есть-ли в нем подводные камни?
Пока не понимаю.
Примерный алгоритм поиска решения:
Код: Выделить всё
cat 2017-06-30_full.txt | grep ", 7"
odlk3_7515_1498741105.011651, 7, 270
odlk3_31868_1498237437.342564, 35, 7
odlk3_19163_1498768687.158794, 483, 717
Код: Выделить всё
cat 2017-06-30_full.txt | grep ", 7" | awk '{for(i=1;i<=NF;i++){if($i=="7") {print $1} } }'
odlk3_31868_1498237437.342564,
Код: Выделить всё
cat 2017-06-30_full.txt | grep ", 7" | awk '{for(i=1;i<=NF;i++){if($i=="7") {print $2} } }'
35,
Код: Выделить всё
cat 2017-06-30_full.txt | grep ", 7" | awk '{for(i=1;i<=NF;i++){if($i=="7") {print $3} } }'
7
Попробуем поменять "принт" на i-тый элемент:
Код: Выделить всё
cat 2017-06-30_full.txt | grep ", 7" | awk '{for(i=1;i<=NF;i++){if($i=="7") {print $i} } }'
7
https://www.ibm.com/developerworks/library/l-awk1/
https://www.ibm.com/developerworks/libr ... k1-pdf.pdf
Пока догадался в чем "соль".
Пробуем добавить еще одно условие, теперь так:
Код: Выделить всё
cat 2017-06-30_full.txt | grep ", 7" | awk '{for(i=1;i<=NF;i++){if($i=="7" || $i=="7,") {print $i} } }'
7,
7
Первая "7," от первой строки, вторая "7" от второй строки и не имеет конечной запятой.
А третьей ("717", "71") и нет, т.к. не проходит под условие.
Модифицирую код в скрипте под пример:
Код: Выделить всё
count=`cat $file | grep ", $i" | awk -v Key="$i" '{for(k=1;k<=NF;k++){ if($k==Key || $k=="Key,"){print $k} } }' | wc -l|awk '{print $1}'`
Хотя уверенности полной пока еще нет - про двойные цифири (это когда 30 и 307).
Правда вручную посчитанный массив с условием 30-307 дал такой-же результат как и скрипт.
Попробовал вручную еще пару массивов перепроверить, вроде тоже правильно получилось.
Но кто знает, всегда-ли это будет верный результат?
- Alex Keda
- стреляли...
- Сообщения: 35456
- Зарегистрирован: 2004-10-18 14:25:19
- Откуда: Made in USSR
- Контактная информация:
awk. Замена поля
а потом считайте что угодно и как угодно