Regex 在图案之间打印几行(第一个图案不唯一)
需要sed/awk/grep/任何可以解决我任务的帮助。 我有一个大文件,我需要从中提取多个连续行 我有开始模式:Regex 在图案之间打印几行(第一个图案不唯一),regex,bash,awk,sed,grep,Regex,Bash,Awk,Sed,Grep,需要sed/awk/grep/任何可以解决我任务的帮助。 我有一个大文件,我需要从中提取多个连续行 我有开始模式: 和结束模式: 中间有几行,如下所示: <DN>234</DN> <DD>sdfsd</DD> <BR>456456</BR> <COL>6575675 sdfsd</COL> <RAC>456464</RAC> <GR>sdfsdfsFFFDd<
和结束模式:
中间有几行,如下所示:
<DN>234</DN>
<DD>sdfsd</DD>
<BR>456456</BR>
<COL>6575675 sdfsd</COL>
<RAC>456464</RAC>
<GR>sdfsdfsFFFDd</GR>
234
自卫队
456456
6575675自卫队
456464
SDFSDFSFDD
我试过这个:
sed -n '/\<DN\>/,/\<\/GR\>/p'
sed-n'/\/,/\/p'
和其他几个(使用awk和sed)。
它可以正常工作,但问题是源文件可能包含以
开头的行,而在一组行的末尾不包含
,然后以另一个和正常结尾的部分开始:
<DN>234</DN> - unneded DN
<AB>sdfsd</AB>
<DC>456456</DC>
<EF>6575675 sdfsd</EF>
....really large piece of unwanted text here....
<DN>234</DN>
<DD>sdfsd</DD>
<BR>456456</BR>
<COL>6575675 sdfsd</COL>
<RAC>456464</RAC>
<GR>sdfsdfsFFFDd</GR>
<RAC>456464</RAC>
<GR>sdfsdfsFFFDd</GR>
234-无编号DN
自卫队
456456
6575675自卫队
…这里有一大块不需要的文字。。。。
234
自卫队
456456
6575675自卫队
456464
SDFSDFSFDD
456464
SDFSDFSFDD
如何只提取需要的行,而忽略包含
的日志的垃圾段,而不结束
接下来,我需要将多行片段从
转换为
到一个单行文件,从
开始,以
结束。
任何帮助都将不胜感激。我被卡住了你可以使用
pcregrep
工具来实现这一点
$ pcregrep -o -M '(?s)(?<=^|\s)<DN>(?:(?!<DN>).)*?</GR>(?=\n|$)' file
<DN>234</DN>
<DD>sdfsd</DD>
<BR>456456</BR>
<COL>6575675 sdfsd</COL>
<RAC>456464</RAC>
<GR>sdfsdfsFFFDd</GR>
$pcregremp-o-M'(?s)(?您可以使用pcregremp
工具进行此操作
$ pcregrep -o -M '(?s)(?<=^|\s)<DN>(?:(?!<DN>).)*?</GR>(?=\n|$)' file
<DN>234</DN>
<DD>sdfsd</DD>
<BR>456456</BR>
<COL>6575675 sdfsd</COL>
<RAC>456464</RAC>
<GR>sdfsdfsFFFDd</GR>
$pcregrep-o-M'(?s)(?awk'
#以“”开头的行开始匹配。
/^/ {
#如果我们看到了一个开始,却没有一个相匹配的结束,那就扔掉我们所保存的一切。
如果(dn){
d=“”
}
#标记位于“”元素中。
dn=1
#保存当前行。
d=0美元
下一个
}
#以“$”结尾的行结束匹配(但仅当我们当前处于匹配中时)。
dn&&/$/{
#我们不再是一个元素了。
dn=0
#打印出我们保存的行和当前行。
打印文件“%s%s%s\n”,d,OFS,$0
#重置保存的内容。
d=“”
下一个
}
#如果我们在一个元素中并且已经保存了内容,则将当前行附加到内容中(由OFS分隔)。
dn&d{
d=d OFS$0
}
"档案"
awk'
#以“”开头的行开始匹配。
/^/ {
#如果我们看到了一个开始,却没有一个相匹配的结束,那就扔掉我们所保存的一切。
如果(dn){
d=“”
}
#标记位于“”元素中。
dn=1
#保存当前行。
d=0美元
下一个
}
#以“$”结尾的行结束匹配(但仅当我们当前处于匹配中时)。
dn&&/$/{
#我们不再是一个元素了。
dn=0
#打印出我们保存的行和当前行。
打印文件“%s%s%s\n”,d,OFS,$0
#重置保存的内容。
d=“”
下一个
}
#如果我们在一个元素中并且已经保存了内容,则将当前行附加到内容中(由OFS分隔)。
dn&d{
d=d OFS$0
}
"档案"
awk'
/^/{n=1}
n{lines[n++]=$0}
n&&/$/{
对于(i=1;iawk'
/^/{n=1}
n{lines[n++]=$0}
n&&/$/{
对于(i=1;i和bash:
fun ()
{
local line output;
while IFS= read -r line; do
if [[ $line =~ ^'<DN>' ]]; then
output=$line;
else
if [[ -n $output ]]; then
output=$output$'\n'$line;
if [[ $line =~ '</GR>'$ ]]; then
echo "$output";
output=;
fi;
fi;
fi;
done
}
fun <file
fun()
{
本地线路输出;
当IFS=读取-r行时;执行
如果[[$line=~^''],则
输出=$行;
其他的
如果[[-n$output]];则
output=$output$'\n'$行;
如果[[$line=~''$]];则
回显“$output”;
输出=;
fi;
fi;
fi;
完成
}
bash的乐趣:
fun ()
{
local line output;
while IFS= read -r line; do
if [[ $line =~ ^'<DN>' ]]; then
output=$line;
else
if [[ -n $output ]]; then
output=$output$'\n'$line;
if [[ $line =~ '</GR>'$ ]]; then
echo "$output";
output=;
fi;
fi;
fi;
done
}
fun <file
fun()
{
本地线路输出;
当IFS=读取-r行时;执行
如果[[$line=~^''],则
输出=$行;
其他的
如果[[-n$output]];则
output=$output$'\n'$行;
如果[[$line=~''$]];则
回显“$output”;
输出=;
fi;
fi;
fi;
完成
}
乐趣这可能适合你(GNU-sed):
sed-n'/{h;b};x;/./G;x;/这可能适合您(GNU-sed):
sed-n'/{h;b};x;//G;x;/谢谢您的回复!不幸的是,您的建议对实际文件不起作用。可能是因为系统将其视为二进制文件,我必须在grep命令中添加-a选项以使其起作用。但是对于pcregrep没有这样的选项。您能将确切的文件内容发布到pastebin中吗?恐怕它太大了。s每一百兆字节的文件只包含我需要提取的几行有价值的数据。它来自生产系统,包含客户机数据。这一行最终对我有用:pcregrep--buffer size=100000000-o-M'(?s)(?谢谢你的回复!不幸的是,你的建议对实际文件不起作用。可能是因为系统将其视为二进制文件,我必须在grep命令中添加-a选项以使其起作用。但是对于pcregrep没有这样的选项。你能在pastebin或你的问题中发布确切的文件内容吗?恐怕它太大了ndred MB的文件只包含我需要提取的几行有价值的数据。它来自生产系统,包含客户机数据。这一行最终对我有用:pcregrep--buffer size=100000000-o-M'(?s)(?哇,谢谢,太棒了。我甚至不知道如何使用它。我应该把它复制到脚本中吗?如果我这样做,什么也不会发生。系统运行几秒钟,然后什么也不打印。但是如果我手动或用grep-a检查,文件确实包含匹配的数据。文件是否有DOS行结尾?grep'$”
是否找到匹配的行?“grep”^'`?实际上文件没有行尾(至少notepad++不显示任何CRLF或类似的内容),它是一种二进制文件,但包含大量文本,并混合了二进制数据。grep-a“^”20140905.log找到许多匹配项。grep“$”20140905.log-不t@IvanBondarets如果文件不是“文本文件”那么在脚本上使用文本工具就不那么可靠了。也就是说,你可以尝试在脚本中使用/
(d
sed -n '/<DN>/{h;b};x;/./G;x;/<\/GR/{x;/./p;z;x}' file