我回答了这个问题,但我陷入了必须为其添加单引号的部分。
就像原始文件一样:
$$BATCHCTRL=TEST-012017
$$STATE=CA AZ
$$FROM_DATE=01/10/2017
$$TO_DATE=01/30/2017
新文件应该是:
$$BATCHCTRL=TEST-012017
$$STATE='CA'
$$FROM_DATE=01/10/2017
$$TO_DATE=01/30/2017
我用了
sed -Ei 's/^\$\$STATE=([A-Z]{2}) ([A-Z]{2})/\$\$STATE=\1/g' sed_file
所以我得到:
$$BATCHCTRL=TEST-012017
$$STATE=CA
$$FROM_DATE=01/10/2017
$$TO_DATE=01/30/2017
但现在我无法在其中添加单引号。我尝试转义,使用双引号而不是单引号,尝试不使用引号,但没有一个起作用。
答案1
两种选择:
暂时脱离作为表达式的单引号字符串sed
,插入"'"
(带引号的单引号字符)并继续。对其他报价重复上述操作。
$ sed -E 's/^\$\$STATE=([A-Z]{2}) ([A-Z]{2})/$$STATE='"'"'\1'"'"'/' file
$$BATCHCTRL=TEST-012017
$$STATE='CA'
$$FROM_DATE=01/10/2017
$$TO_DATE=01/30/2017
请注意,$
不必在替换字符串中进行转义。
您还可以使用\'
代替"'"
:
$ sed -E 's/^\$\$STATE=([A-Z]{2}) ([A-Z]{2})/$$STATE='\''\1'\''/' file
$$BATCHCTRL=TEST-012017
$$STATE='CA'
$$FROM_DATE=01/10/2017
$$TO_DATE=01/30/2017
或者,
在表达式周围使用双引号,并在其中使用单引号作为普通字符。这要求$
保护所有现有的反斜杠和字符免受 shell 的影响。
$ sed -E "s/^\\\$\\\$STATE=([A-Z]{2}) ([A-Z]{2})/\$\$STATE='\1'/" file
$$BATCHCTRL=TEST-012017
$$STATE='CA'
$$FROM_DATE=01/10/2017
$$TO_DATE=01/30/2017
这里需要过多的转义,因为您想要获取正则表达式中的sed
文字字符串(以及替换部分中的文字字符串)。在 shell 中的双引号内,只是一个文字。 将是一个反斜杠,后跟,shell 会尝试使用 后面的任何内容作为扩展(或例如)。使用,我们给出一个文字反斜杠,后跟文字。\$
$
\$
$
\\$
$
$
$$
$STATE
\\\$
$
我还删除了表达式g
末尾的sed
。由于您将其锚定在行的开头,因此我们预计替换不会执行多次。
答案2
FWIW,您可以使用以下命令替换bash
命令行sed
调用中单引号中的加号,如下所示:
$ sed -e 's/$$STATE=\([A-Z][A-Z]\) [A-Z][A-Z]$/$$STATE='"'\1'/" sed_file
这样,您就可以避免“过度反斜杠”(已知会导致“反斜杠炎”)。
有几点需要思考:
$
当在 s/// 命令的 lhs 上除最后一个以外的任何地方使用时,都会丢失其元字符状态。Ofc,你必须用单引号括起来,无论如何 bash 都会启动并扩展变量。我正在谈论 sed 的作用。在 s/// 命令的右侧,$ 不是元字符,因此无需对其进行转义。
sed 将处于 -e 模式而不是 -re 模式。
华泰
答案3
我尝试过以下方法
sed "/^\$\$STATE/s/ .*/'/g" filename| sed "/\$\$STATE/s/=/&'/g"
输出
$$BATCHCTRL=TEST-012017
$$STATE='CA'
$$FROM_DATE=01/10/2017
$$TO_DATE=01/30/201