замена сложной строки sed / awk - PullRequest
1 голос
/ 09 июля 2020

Я хочу заменить тысячи таких строк, но мне трудно заставить его работать, также у меня есть 2 переменные $ time и $ date condition, чтобы не делать их глобальными.:

1002 * Пример: <!-- 2020-07-06 16:45:00 WEST / 1594050300 --> <row><v>5.0000000000e+00</v></row>

Для замены: <!-- 2020-07-06 16:45:00 WEST / 1594050300 --> <row><v>NaN</v></row>

Я пробовал использовать sed:

sed -i '<!-- 2020-07-06 16:45:00 WEST \/ 1594050300 --> <row><v>5.0000000000e+00<\/v><\/row>.*/<!-- 2020-07-06 16:45:00 WEST \/ 1594050300 --> <row><v>NaN<\/v><\/row>/' dump_teste.xml

sed: -e выражение # 1, char 1: unknown команда: `<'</p>

Также с awk:

awk '{gsub(/<!-- 2020-07-08 12:00:00 WEST / 1594206000 --> <row><v>1.9933333333e+00</v></row>/,"<!-- 2020-07-08 12:00:00 WEST / 1594206000 --> <row><v>NaN</v></row>")}1' tmp.txt
    awk: cmd. line:1: {gsub(/<!-- 2020-07-08 12:00:00 WEST / 1594206000 --> <row><v>1.9933333333e+00</v></row>/,"<!-- 2020-07-08 12:00:00 WEST / 1594206000 --> <row><v>NaN</v></row>")}1
    awk: cmd. line:1:                                                     ^ syntax error
    awk: cmd. line:1: {gsub(/<!-- 2020-07-08 12:00:00 WEST / 1594206000 --> <row><v>1.9933333333e+00</v></row>/,"<!-- 2020-07-08 12:00:00 WEST / 1594206000 --> <row><v>NaN</v></row>")}1
    awk: cmd. line:1:                                                                               ^ syntax error
    awk: cmd. line:1: {gsub(/<!-- 2020-07-08 12:00:00 WEST / 1594206000 --> <row><v>1.9933333333e+00</v></row>/,"<!-- 2020-07-08 12:00:00 WEST / 1594206000 --> <row><v>NaN</v></row>")}1
    awk: cmd. line:1:                                                                                                                                         ^ syntax error
    awk: cmd. line:1: {gsub(/<!-- 2020-07-08 12:00:00 WEST / 1594206000 --> <row><v>1.9933333333e+00</v></row>/,"<!-- 2020-07-08 12:00:00 WEST / 1594206000 --> <row><v>NaN</v></row>")}1
    awk: cmd. line:1:                                                                                                                                                      ^ syntax error
    awk: cmd. line:1: {gsub(/<!-- 2020-07-08 12:00:00 WEST / 1594206000 --> <row><v>1.9933333333e+00</v></row>/,"<!-- 2020-07-08 12:00:00 WEST / 1594206000 --> <row><v>NaN</v></row>")}1
    awk: cmd. line:1:                                                                                                                                                                ^ unterminated string
    awk: cmd. line:1: {gsub(/<!-- 2020-07-08 12:00:00 WEST / 1594206000 --> <row><v>1.9933333333e+00</v></row>/,"<!-- 2020-07-08 12:00:00 WEST / 1594206000 --> <row><v>NaN</v></row>")}1
    awk: cmd. line:1:                                                                                                                                                                ^ syntax error

или

awk '{sub(/<!-- 2020-07-08 12:00:00 WEST / 1594206000 --> <row><v>1.9933333333e+00</v></row>/,"<!-- 2020-07-08 12:00:00 WEST / 1594206000 --> <row><v>NaN</v></row>")}1' tmp.txt
awk: cmd. line:1: {sub(/<!-- 2020-07-08 12:00:00 WEST / 1594206000 --> <row><v>1.9933333333e+00</v></row>/,"<!-- 2020-07-08 12:00:00 WEST / 1594206000 --> <row><v>NaN</v></row>")}1
awk: cmd. line:1:                                                    ^ syntax error
awk: cmd. line:1: {sub(/<!-- 2020-07-08 12:00:00 WEST / 1594206000 --> <row><v>1.9933333333e+00</v></row>/,"<!-- 2020-07-08 12:00:00 WEST / 1594206000 --> <row><v>NaN</v></row>")}1
awk: cmd. line:1:                                                                              ^ syntax error
awk: cmd. line:1: {sub(/<!-- 2020-07-08 12:00:00 WEST / 1594206000 --> <row><v>1.9933333333e+00</v></row>/,"<!-- 2020-07-08 12:00:00 WEST / 1594206000 --> <row><v>NaN</v></row>")}1
awk: cmd. line:1:                                                                                                                                        ^ syntax error
awk: cmd. line:1: {sub(/<!-- 2020-07-08 12:00:00 WEST / 1594206000 --> <row><v>1.9933333333e+00</v></row>/,"<!-- 2020-07-08 12:00:00 WEST / 1594206000 --> <row><v>NaN</v></row>")}1
awk: cmd. line:1:                                                                                                                                                     ^ syntax error
awk: cmd. line:1: {sub(/<!-- 2020-07-08 12:00:00 WEST / 1594206000 --> <row><v>1.9933333333e+00</v></row>/,"<!-- 2020-07-08 12:00:00 WEST / 1594206000 --> <row><v>NaN</v></row>")}1
awk: cmd. line:1:                                                                                                                                                               ^ unterminated string
awk: cmd. line:1: {sub(/<!-- 2020-07-08 12:00:00 WEST / 1594206000 --> <row><v>1.9933333333e+00</v></row>/,"<!-- 2020-07-08 12:00:00 WEST / 1594206000 --> <row><v>NaN</v></row>")}1
awk: cmd. line:1:                                                                                                                                                               ^ syntax error

Ответы [ 2 ]

2 голосов
/ 09 июля 2020

У команды, которую вы пытаетесь, нет опции s, поэтому она выдает ошибку.

sed -i 's/<!-- 2020-07-06 16:45:00 WEST \/ 1594050300 --> <row><v>5.0000000000e+00<\/v><\/row>.*/<!-- 2020-07-06 16:45:00 WEST \/ 1594050300 --> <row><v>NaN<\/v><\/row>/g' dumpteste.xml

или

sed -i 's/<v>.*<\/v>/<v>NAN<\/v>/g' dumpteste.xml

У вас есть две переменные $ date и $ time и вы хотите чтобы сопоставить строки с этими переменными, а затем применить sed. Сделайте следующее:

sed "/"$date" "$time" .*<\/row>/ s/<v>.*<\/v>/<v>NAN<\/v>/g" dumpteste.xml

В приведенной выше команде, если строка

<!-- 2020-07-06 16:45:00 WEST / 1594050300 --> <row><v>5.0000000000e+00</v></row>```
And date and time variable are
date='2020-07-06' time='16:45:00' 
then only line containg that date and time will be edited by sed.


Did it solved your problem?
0 голосов
/ 09 июля 2020

В соответствии с вашими потребностями ниже приведена команда для замены числа на NAN в файле с учетом всех строк, попадающих во временной диапазон, независимо от порядка, в котором появляются строки.

set date from and till variables and then below command

while IFS= read -r in; do out="$(echo "$in" | awk '{print $2}')" && outtime="$(echo "$in" | awk '{print $3}')" && sed -i "/"$out" "$outtime"/ s/<v>.*<\/v>/<v>NAN<\/v>/" dumpteste.xml; done <<< "$(sort -k3 -k4 -k5 dumpteste.xml | awk -v date="$date" -v from="$from" -v till="$till" '$2 == date && $3 >= from && $3 <= till' | tac)"

Пример приведенной выше команды

cat dumpteste.xml         #original file
<!-- 2020-07-06 16:45:00 WEST / 1594050300 --> <row><v>5.0000000000e+00</v></row>
<!-- 2020-07-06 16:47:00 WEST / 1594050300 --> <row><v>5.0000000000e+00</v></row>
<!-- 2020-07-06 17:47:00 WEST / 1594050300 --> <row><v>5.0000000000e+00</v></row>
<!-- 2020-07-06 16:45:00 WEST / 1594050300 --> <row><v>5.0000000000e+00</v></row>
<!-- 2020-07-06 16:48:00 WEST / 1594050300 --> <row><v>5.0000000000e+00</v></row>
<!-- 2020-07-06 17:45:00 WEST / 1594050300 --><row<v>5.0000000000e+00</v></row>
<!-- 2020-08-06 16:45:00 WEST / 1594050300 --> <row><v>5.0000000000e+00</v></row>



date=2020-07-06
from=16:45:00
till=17:45:00
 Output  
cat dumpteste.xml      #after change

<!-- 2020-07-06 16:45:00 WEST / 1594050300 --> <row><v>NAN</v></row>
<!-- 2020-07-06 16:47:00 WEST / 1594050300 --> <row><v>NAN</v></row>
<!-- 2020-07-06 17:47:00 WEST / 1594050300 --> <row><v>5.0000000000e+00</v></row>
<!-- 2020-07-06 16:45:00 WEST / 1594050300 --> <row><v>NAN</v></row>
<!-- 2020-07-06 16:48:00 WEST / 1594050300 --> <row><v>NAN</v></row>
<!-- 2020-07-06 17:45:00 WEST / 1594050300 --> <row><v>NAN</v></row>
<!-- 2020-08-06 16:45:00 WEST / 1594050300 --> <row><v>5.0000000000e+00</v></row>

См. Даты 2020-07-06, когда диапазон времени 16: 45: 00-17: 45: 00 предоставляется строками со временем 16: 45,16: 48,16: 47,17 : 45 изменены. Для времени 16:45, но даты 2020-08-06 оно не изменилось, поскольку дата не совпадает.

Также, если вам нужно ввести дату в диапазоне, определите четыре переменные: date, enddate, from, to. И выполните команду ниже

date=2020-07-06
enddate=2020-08-06
from=16:45:00
till=17:45:00
while IFS= read -r in; do out="$(echo "$in" | awk '{print $2}')" && outtime="$(echo "$in" | awk '{print $3}')" && sed -i "/"$out" "$outtime"/ s/<v>.*<\/v>/<v>NAN<\/v>/" du*; done <<< "$(sort -k3 -k4 -k5 du* | awk -v date="$date" -v from="$from" -v till="$till" -v enddate="$enddate" '$2 >= date && $2 <= enddate && $3 >= from && $3 <= till' | tac)"

Вышеуказанная команда поможет вам в вашей задаче по изменению значений, предоставленных с датой и временем в диапазоне. Надеюсь, этого достаточно?

Укороченная версия: 1). С временным диапазоном

date=2020-07-06 && from=16:45:00 && till=17:45:00 && gawk -i inplace -v date="$date" -v from="$from" -v till="$till" '$2 == date && $3 >= from && $3 <= till {gsub(/<v>[^<]*/, "<v>nan<")}1' dumpteste.xml

2). С диапазоном даты и времени

date=2020-07-06 && from=16:45:00 && till=17:45:00 && enddate=2020-08-06 && awk -v date="$date" -v from="$from" -v till="$till" -v enddate="$enddate" '$2 >= date && $2 <= enddate && $3 >= from && $3 <= till {gsub(/<v>[^<]*/, "<v>nan<")}1' dumpteste.xml
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...