修改问题的答案
给定输入:
<?xml version="1.0" encoding="UTF-8" ?><InputRecord xmlns:xsi= "http://www.w3.org/2001/XMLSchema-instance" <tag1>blah</tag1><mytag>myinfo</mytag><tag2>blah</tag2></InputRecord>
<?xml version="1.0" encoding="UTF-8" ?><InputRecord xmlns:xsi= "http://www.w3.org/2001/XMLSchema-instance" <tag1>blah1</tag1><mytag>myinfo1</mytag><tag2>blah2</tag2></InputRecord>
输出应该是:
myinfo
myinfo1
暂时忽略使用正则表达式解析 XML 通常是不明智的,这可以被视为在单行上查找开始标记和结束标记之间的文本的请求。这转化为:
starttag="<mytag>"
endtag="</mytag>"
sed -n "\%.*$starttag\(.*\)$endtag.*% s//\1/p"
POSIX 要求该\%
符号sed
允许使用斜杠以外的其他内容作为正则表达式的分隔符。POSIXsed
说:
... 一个上下文地址(由 BRE 组成,如正则表达式中所述sed
,前后有一个分隔符,通常是 a <slash>
)
和:
在上下文地址中,除 or 以外的任何字符 的"\cBREc"
结构应c
与相同。如果 指定的字符出现在 a之后,那么它应该被认为是那个字面字符,它不会终止 BRE。例如,在上下文 address中,第二个代表它自己,因此 BRE 是。<backslash>
<newline>
"/BRE/"
c
<backslash>
"\xabc\xdefx"
x
"abcxdef"
回答问题的原始版本
$endline
如果您获得正确的值,您的脚本应该可以正常工作。但是,IMNSHO,对打印范围持肯定态度更简单:
sed -n "/$startline/,/$endline/p" input.txtt > test.txt
意思是“-n
除非我告诉你,否则不要打印”,脚本方式“在与起始行匹配的行和与结束行匹配的行之间打印。
对于带有斜杠的结束标记,您需要使用反斜杠转义斜杠:
endline="<\/Nexttag>"
或者您可以使用 a.
代替斜线,理论上它可以匹配开头<XNexttag>
但可能不会匹配。没有反斜杠可以解释为什么你得到了从开始行到文件结尾的所有内容。
关于积极性的好处
考虑数据文件:
line1
line2 start1
line3
line4 end1
line5
line6 start2
line7
line8 end2
line9
并考虑 shell 和sed
命令:
echo Positive Single
sed -n -e '/start1/,/end1/p' data
echo Negative Single
sed -e '/start1/,/end1/!d' data
echo Positive Double
sed -n -e '/start1/,/end1/p' -e '/start2/,/end2/p' data
echo Negative Double
sed -e '/start1/,/end1/!d' -e '/start2/,/end2/!d' data
运行该脚本的输出是:
$ sh sed.scripts
Positive Single
line2 start1
line3
line4 end1
Negative Single
line2 start1
line3
line4 end1
Positive Double
line2 start1
line3
line4 end1
line6 start2
line7
line8 end2
Negative Double
$
!d
对于要匹配的单个模式范围的情况,公式与-n
加公式没有问题p
。
但是,“正双”模式工作正常,产生了我期望的答案,“打印start1和end1之间的线以及start2和end2之间的线”,而“负双”模式不能正常工作更多的。我宁愿使用可扩展的版本,也不愿使用在需求发生变化时必须重写的版本。