#shell #awk #sed
#оболочка #awk #sed
Вопрос:
У меня есть большой текстовый файл (myfile.txt ), где ровно для одной строки я пытаюсь заменить значение «0.999999999» другим числом, скажем, «0.111111111».
expression "if((CONDITION1==1),0.999999999,CATEGORY1)"
Строка может быть однозначно идентифицирована путем поиска как строки перед ней, так и за ней (должны быть оба вместе, иначе шаблон не уникален), или в этом случае
'expression "if((CONDITION1==1),'
and
',CATEGORY1)"'
После изучения нескольких других сообщений я нахожу, что сложная часть в моем случае заключается в
- определите конкретную строку по нескольким шаблонам и
- замена строки, по которой невозможно выполнить поиск сам по себе (поскольку она может измениться)
Первая проблема, которую я вижу, была решена в других сообщениях, но я в тупике по второму.
Я пробовал несколько разных способов, но ни один из них не дает правильных результатов, ближайший, который я получил, это :
sed -n '/if((CONDITION1==1).CATEGORY1)/{ s/,*,/,0.111111111,/p }' myfile.txt
Где я пытаюсь идентифицировать строки, просматривая часть строк префикса и суффикса, а затем пытаясь заменить все между и включая две запятые.
Мои вопросы:
- что я делаю не так?
- является ли sed лучшим инструментом для этой задачи, или awk или perl справятся лучше? Спасибо.
=============== РЕДАКТИРОВАТЬ==============
Я обновил свой код на основе версии @Ed, чтобы иметь возможность считывать значение из переменной, извлеченной из этого файла, во время выполнения кода на основе ввода. Надеюсь, это поможет кому-нибудь позже:
#test.sh
month= $1
VAL= $(cat data_$month.dat | awk 'NR==2')
echo "VAL is:" $VAL
sed -i 's/(expression "if((CONDITION1==1),)[^,]*(,CATEGORY1)")/1'"${VAL}"'2/' file
Ответ №1:
$ sed 's/(expression "if((CONDITION1==1),)[^,]*(,CATEGORY1)")/10.1111111112/' file
expression "if((CONDITION1==1),0.111111111,CATEGORY1)"
Вот пример того, почему часть, которую вы не записываете, должна быть [^,]*
вместо .*
:
$ cat file
expression "if((CONDITION1==1),0.999999999,CATEGORY1)" # this is ",CATEGORY1)"
expression "if((CONDITION1==1),0.999999999,FOO)" # this is not ",CATEGORY1)"
$ sed 's/(expression "if((CONDITION1==1),)[^,]*(,CATEGORY1)")/10.1111111112/' file
expression "if((CONDITION1==1),0.111111111,CATEGORY1)" # this is ",CATEGORY1)"
expression "if((CONDITION1==1),0.999999999,FOO)" # this is not ",CATEGORY1)"
$ sed 's/(expression "if((CONDITION1==1),).*(,CATEGORY1)")/10.1111111112/' file
expression "if((CONDITION1==1),0.111111111,CATEGORY1)"
expression "if((CONDITION1==1),0.111111111,CATEGORY1)"
Комментарии:
1. Спасибо, Эд. Ваш код делает именно то, что я искал
Ответ №2:
если ваши данные в файле ‘d’, попробуйте gnu sed:
sed -E 'h;s/expression "if((CONDITION1==1),([0-9.] ),CATEGORY1)"/1/;s/9/1/g;G;s/(. )n([^,] ,)[^,] (,. )/213/' d