提取两个字符串之间的文本并对其执行操作
Extract text between two string and perform operation on it
我有一个包含以下文本的文件
<MY_TEXT="XYZ" PATH="MNO" #First occurrence of MY_TEXT
<location= "XYZ" path="ABC"
\location>
<R_DATA = MNOP
<Mylocation ="ghdf" stime=20150301 etime=20150401 >
<Mylocation ="ghdf" stime=20150401 etime=20150501 >
\R_DATA>
<Blah>
\MY_TEXT> #Second occurrence of MY_TEXT
<MY_TEXT="ABC" PATH="EFG" #Third occurrence of MY_TEXT
<location= "QQQ" path="LLL"
\location>
<R_DATA = MNOP
<Mylocation ="ghdf" stime=20150301 etime=20150401 >
<Mylocation ="ghdf" stime=20150401 etime=20150501 >
\R_DATA>
<Blah>
\MY_TEXT> #Fourth occurrence of MY_TEXT
我的任务是找到包含 <MY_TEXT="XYZ"
的行中的文本,它可能在开头有空格,然后找到它的结尾 \MY_TEXT
所以输出是
<MY_TEXT="XYZ" PATH="MNO" #First occurrence of MY_TEXT
<location= "XYZ" path="ABC"
\location>
<R_DATA = MNOP
<Mylocation ="ghdf" stime=20150301 etime=20150401 > #First occurrence of Mylocation
<Mylocation ="ghdf" stime=20150401 etime=20150501 > #Second occurrence of Mylocation
\R_DATA>
<Blah>
\MY_TEXT>
然后它找到最后一次出现的 Mylocation 即 #Second occurrence of Mylocation
并将文本 etime=20150501
修改为 something
并在文件内联后追加一个新行。
我遇到了这个 link Sed to extract text between two strings 。但是在这里使用 sed 命令要么让我
当我使用 -n 选项时什么也没有,或者当我删除 -n 时打印整个文件。
所以我无法进一步处理文本,因为我无法首先提取我想要的文本。
我也试过 sed -n '/^ *START=A *$/,/^ *END *$/p' yourfile
。但是没有用。你们能帮帮我吗,因为我的脚本不是很好。提前致谢。
这对 sed 有点棘手,但我会尝试一下。
重要说明:这看起来像是一种定义明确的文件格式,但我不认识它。查看是否有直接处理这种格式的工具而不是像 sed 必须的那样将其视为平面文件可能是谨慎的做法。这样的解决方案很可能比直接文本黑客更短、更容易理解并且更健壮。
也就是说,您可以使用
sed -n '/<MY_TEXT="XYZ"/ { :a /\MY_TEXT>/! { N; ba }; s/\(.*\)\(<Mylocation\)/\MY_TEXT>\n/; h; s/.*\MY_TEXT>\n//; s/etime=[0-9]\+/etime=something/; s/\n/\n\n/; s/$/\MY_TEXT>/; G; s/\(.*\)\MY_TEXT>\n\(.*\)\MY_TEXT>\n\(.*\)//; p }' filename
输出:
<MY_TEXT="XYZ" PATH="MNO" #First occurrence of MY_TEXT
<location= "XYZ" path="ABC"
\location>
<R_DATA = MNOP
<Mylocation ="ghdf" stime=20150301 etime=20150401 >
<Mylocation ="ghdf" stime=20150401 etime=something >
\R_DATA>
<Blah>
\MY_TEXT>
其中最令人困惑的一点是使用 \MY_TEXT>\n
作为分隔工作块的标记;这样做是因为我们知道它没有出现在文本的其他任何地方。 \MY_TEXT>
首先出现在我们正在处理的块的最后一行,因此在输入数据中它之后永远不会有换行符。 (代码可能会更清楚一些没有出现在文本中的东西,但我不知道有什么更明显的东西)。
代码的工作原理如下:
#!/bin/sed -nf
/<MY_TEXT="XYZ"/ { # If we find the starter
# line:
:a
/\MY_TEXT>/! { # fetch the rest of the
N # block into the
ba # pattern space
}
s/\(.*\)\(<Mylocation\)/\MY_TEXT>\n/ # mark the place before
# the last Mylocation tag
h # copy that to the hold
# buffer
s/.*\MY_TEXT>\n// # remove the stuff before
# the marker
s/etime=[0-9]\+/etime=something/ # replace the etime
# attribute
s/\n/\n\n/ # insert the new line
s/$/\MY_TEXT>/ # put a marker at the end
G # fetch back the stuff
# from the hold buffer
s/\(.*\)\MY_TEXT>\n\(.*\)\MY_TEXT>\n\(.*\)// # replace the end chunk
# with the edited version
p # print the result.
}
简单的解决方案是使用 range
awk '/<MY_TEXT="XYZ"/,/\MY_TEXT/' file
<MY_TEXT="XYZ" PATH="MNO" #First occurrence of MY_TEXT
<location= "XYZ" path="ABC"
\location>
<R_DATA = MNOP
<Mylocation ="ghdf" stime=20150301 etime=20150401 >
<Mylocation ="ghdf" stime=20150401 etime=20150501 >
\R_DATA>
<Blah>
\MY_TEXT> #Second occurrence of MY_TEXT
或sed
sed -n '/<MY_TEXT="XYZ"/,/\MY_TEXT/p' file
<MY_TEXT="XYZ" PATH="MNO" #First occurrence of MY_TEXT
<location= "XYZ" path="ABC"
\location>
<R_DATA = MNOP
<Mylocation ="ghdf" stime=20150301 etime=20150401 >
<Mylocation ="ghdf" stime=20150401 etime=20150501 >
\R_DATA>
<Blah>
\MY_TEXT> #Second occurrence of MY_TEXT
我有一个包含以下文本的文件
<MY_TEXT="XYZ" PATH="MNO" #First occurrence of MY_TEXT
<location= "XYZ" path="ABC"
\location>
<R_DATA = MNOP
<Mylocation ="ghdf" stime=20150301 etime=20150401 >
<Mylocation ="ghdf" stime=20150401 etime=20150501 >
\R_DATA>
<Blah>
\MY_TEXT> #Second occurrence of MY_TEXT
<MY_TEXT="ABC" PATH="EFG" #Third occurrence of MY_TEXT
<location= "QQQ" path="LLL"
\location>
<R_DATA = MNOP
<Mylocation ="ghdf" stime=20150301 etime=20150401 >
<Mylocation ="ghdf" stime=20150401 etime=20150501 >
\R_DATA>
<Blah>
\MY_TEXT> #Fourth occurrence of MY_TEXT
我的任务是找到包含 <MY_TEXT="XYZ"
的行中的文本,它可能在开头有空格,然后找到它的结尾 \MY_TEXT
所以输出是
<MY_TEXT="XYZ" PATH="MNO" #First occurrence of MY_TEXT
<location= "XYZ" path="ABC"
\location>
<R_DATA = MNOP
<Mylocation ="ghdf" stime=20150301 etime=20150401 > #First occurrence of Mylocation
<Mylocation ="ghdf" stime=20150401 etime=20150501 > #Second occurrence of Mylocation
\R_DATA>
<Blah>
\MY_TEXT>
然后它找到最后一次出现的 Mylocation 即 #Second occurrence of Mylocation
并将文本 etime=20150501
修改为 something
并在文件内联后追加一个新行。
我遇到了这个 link Sed to extract text between two strings 。但是在这里使用 sed 命令要么让我 当我使用 -n 选项时什么也没有,或者当我删除 -n 时打印整个文件。 所以我无法进一步处理文本,因为我无法首先提取我想要的文本。
我也试过 sed -n '/^ *START=A *$/,/^ *END *$/p' yourfile
。但是没有用。你们能帮帮我吗,因为我的脚本不是很好。提前致谢。
这对 sed 有点棘手,但我会尝试一下。
重要说明:这看起来像是一种定义明确的文件格式,但我不认识它。查看是否有直接处理这种格式的工具而不是像 sed 必须的那样将其视为平面文件可能是谨慎的做法。这样的解决方案很可能比直接文本黑客更短、更容易理解并且更健壮。
也就是说,您可以使用
sed -n '/<MY_TEXT="XYZ"/ { :a /\MY_TEXT>/! { N; ba }; s/\(.*\)\(<Mylocation\)/\MY_TEXT>\n/; h; s/.*\MY_TEXT>\n//; s/etime=[0-9]\+/etime=something/; s/\n/\n\n/; s/$/\MY_TEXT>/; G; s/\(.*\)\MY_TEXT>\n\(.*\)\MY_TEXT>\n\(.*\)//; p }' filename
输出:
<MY_TEXT="XYZ" PATH="MNO" #First occurrence of MY_TEXT
<location= "XYZ" path="ABC"
\location>
<R_DATA = MNOP
<Mylocation ="ghdf" stime=20150301 etime=20150401 >
<Mylocation ="ghdf" stime=20150401 etime=something >
\R_DATA>
<Blah>
\MY_TEXT>
其中最令人困惑的一点是使用 \MY_TEXT>\n
作为分隔工作块的标记;这样做是因为我们知道它没有出现在文本的其他任何地方。 \MY_TEXT>
首先出现在我们正在处理的块的最后一行,因此在输入数据中它之后永远不会有换行符。 (代码可能会更清楚一些没有出现在文本中的东西,但我不知道有什么更明显的东西)。
代码的工作原理如下:
#!/bin/sed -nf
/<MY_TEXT="XYZ"/ { # If we find the starter
# line:
:a
/\MY_TEXT>/! { # fetch the rest of the
N # block into the
ba # pattern space
}
s/\(.*\)\(<Mylocation\)/\MY_TEXT>\n/ # mark the place before
# the last Mylocation tag
h # copy that to the hold
# buffer
s/.*\MY_TEXT>\n// # remove the stuff before
# the marker
s/etime=[0-9]\+/etime=something/ # replace the etime
# attribute
s/\n/\n\n/ # insert the new line
s/$/\MY_TEXT>/ # put a marker at the end
G # fetch back the stuff
# from the hold buffer
s/\(.*\)\MY_TEXT>\n\(.*\)\MY_TEXT>\n\(.*\)// # replace the end chunk
# with the edited version
p # print the result.
}
简单的解决方案是使用 range
awk '/<MY_TEXT="XYZ"/,/\MY_TEXT/' file
<MY_TEXT="XYZ" PATH="MNO" #First occurrence of MY_TEXT
<location= "XYZ" path="ABC"
\location>
<R_DATA = MNOP
<Mylocation ="ghdf" stime=20150301 etime=20150401 >
<Mylocation ="ghdf" stime=20150401 etime=20150501 >
\R_DATA>
<Blah>
\MY_TEXT> #Second occurrence of MY_TEXT
或sed
sed -n '/<MY_TEXT="XYZ"/,/\MY_TEXT/p' file
<MY_TEXT="XYZ" PATH="MNO" #First occurrence of MY_TEXT
<location= "XYZ" path="ABC"
\location>
<R_DATA = MNOP
<Mylocation ="ghdf" stime=20150301 etime=20150401 >
<Mylocation ="ghdf" stime=20150401 etime=20150501 >
\R_DATA>
<Blah>
\MY_TEXT> #Second occurrence of MY_TEXT