START
在一个文件中,在一个由模式和标记的部分之前和之后有任何乱码文本END
(特定字符串仅出现一次,并且以正确的顺序出现在同一行上)。我想只对和之间的部分进行一些字符串START
操作END
示例输入:
aomodi3hriq32| ¶³r 0q93aoiSTART_this_is_to_be_modified_ENDaqsdofuha23uru| ²23i ii3uhfia
oawpo3<9"§ A hSTART_this_also_needs_modification_ENDqa 032/a237(°1Q"§ >A_this_
START changeme ENDnot_this_modias
在 - 操作方面,应该修改和sed
之间的子字符串(和仅子字符串),就像我使用.START
END
sed 's/_this_// ; s/modi/MODI/ ; y/as/45/'
示例输出:
aomodi3hriq32| ¶³r 0q93aoiSTARTi5_to_be_MODIfied_ENDaqsdofuha23uru| ²23i ii3uhfia
oawpo3<9"§ A hSTART4l5o_need5_MODIfic4tion_ENDqa 032/a237(°1Q"§ >A_this_
START ch4ngeme ENDnot_this_modias
awk
withFS="START|END"
失败,因为OFS
不能在不同位置设置多个值。
我尝试使用sed
嵌套命令替换和不同的分隔符 ( ~
) 但失败了,并且还担心之前START
/之后可能有字符END
会与命令混淆(例如 a /
)。这个想法是只选择“内部”子字符串并执行操作,然后将其用作替换的一部分:
sed "s/^\(.*\)START.*END\(.*\)$/\1$(sed 's~^.*START~~
s~END.*~~
s~_this_~~
s~modi~MODI~
y~as~45~' infile)\2/" infile
我不熟悉例如perl
....但无论如何。
有没有办法让一组 -sed
操作仅适用于一行的 REGEX 匹配的子字符串?
-CSD
解码来自 UTF-8 的输入并将输出编码为 UTF-8$before
,$between
和$after
,我们可以使用/p
and${^PREMATCH}
,${^POSTMATCH}
但我没有找到更好的解决方案:如果 START...END 部分可以在一行上重复,则需要遍历每一行。
使用标准
sed
并假设每一行都包含一个START
和一个END
子字符串(按此顺序):测试:
内联,在命令行上:
也许带有
awk
和字符串函数:您始终可以构建自己的多个 OFS:
请注意,gsub() 的第一个参数是正则表达式,因此在定义
map=....
;时要小心。他们的右手映射也不应该有一些特殊字符,例如&
، back-references\1
等;但是,当您手动编写映射时,您可以转义任何特殊字符以避免它们被 gsub() 专门解释。正如您提到的,我使用 CR
\r
来分隔映射,这是您输入文件中唯一不存在的东西,除此之外\0
,它不能在 split() 和 awk 中的其他函数(或者也可能在其他编程语言中)中使用,因为 awk 会只考虑\0
一个字符串中最多可以存在一个。因此,每个左侧的正则表达式(此处为字符串)都将被数组中的tr[i]
下一个右侧正则表达式替换。tr[i+1]
tr
使用这种方式将使您免于为每一对编写多个 gsub() 。
这个 GNU
sed
给出了想要的结果在每个 Unix 机器上的任何 shell 中使用任何 awk:
我提出了一个解决方案,它也将
约束:我假设您的文件不使用 4 个字符,我选择了“经常使用”“\001”到“\004”(但可以使用任何其他未使用的 4 个字符)
(因为我使用:\001 使任何 END 以换行符开头,任何 END 以换行符结尾,强制“START(nonSTARTnorEND)END”以外的任何其他组合位于单独的行上,因此不考虑。我使用 \ 004 来“保存”原始文件换行符并在最后恢复它们。我使用 \002 代表一个 START,\003 代表一个 END,让我可以检查两者之间是否也没有这些(并且当我查找要替换的字符串时,我以 START 开头并以 END 结尾)。由于这些替换,所有这些都是允许的。
可以这样做:
注意:这可以进一步简化(不需要用 \002 替换 START 也不需要用 \003 结束,我首先这样做是为了也能够使用 :
[^\002\003]*
来确保中间字符串不包含任何一个,但是 \001-> \n 确保已经...)只要您在 s/// 命令中使用带有 /e 标志的 GNU sed,您就可以做您正在尝试的事情:
上面可以分解成函数,让它看起来更干净。在这里,我们定义了帮助函数和变量以消除混乱:
使用 Perl,这很自然:
或者,POSIXly 我们可以将模式空间划分为 3 个部分,存储在保持中,然后转换中间部分并将它们缝合回去。