我需要在多次出现的文件中将X转换为Y,每次匹配将保存到文件的出现次数。
这是一个示例文件(demo.txt):
\x00START how are you? END\x00
\x00START good thanks END\x00
sometimes random things\x00\x00 inbetween it (ignore this text)
\x00START thats nice END\x00
现在运行命令后,除了&#之外,每个文件(/folder/demo1.txt,/folder/demo2.txt等)的内容应该是\ x00START和END \ x00之间的内容(\ x00为空) 39; START'但不是'结束'
/folder/demo1.txt应该说" START你好吗? ",/ folder / demo2.txt应该说" START非常感谢"。
所以基本上它应该管道#34;你好吗?"并使用' echo'我可以在前面加上' START'。
值得记住的是,我正在处理一个非常大的二进制文件。
我目前正在使用
sed -n -e '/\x00START/,/END\x00/ p' demo.txt > demo1.txt
但是这没有达到预期的效果(它在' \ x00START'之前排队,并且不会在第一个' END \ x00&#停止#' 39。)
答案 0 :(得分:1)
您可以使用grep
:
grep -Po "START\s+\K.*?(?=END)" file
how are you?
good thanks
thats nice
说明:
-P
允许Perl正则表达式-o
仅提取匹配的模式-K
积极向后看(?=something)
积极向前看 编辑:要将\00
与START
匹配,END
可能会出现在:
echo -e '\00START hi how are you END\00' | grep -aPo '\00START\K.*?(?=END\00)'
hi how are you
EDIT2:使用grep的解决方案只匹配单行,对于多行,最好使用perl
。语法非常相似:
echo -e '\00START hi \n how\n are\n you END\00' | perl -ne 'BEGIN{undef $/ } /\A.*?\00START\K((.|\n)*?)(?=END)/gm; print $1'
hi
how
are
you
这里有什么新鲜事:
undef $/
取消定义INPUT分隔符$/
,默认为'\ n'(.|\n)*
点几乎匹配任何字符,但不匹配
\n
所以我们需要在此处添加。/gm
修改器,g
用于多行的全局m
答案 1 :(得分:1)
如果你有 GNU awk
,请尝试:
awk -v RS='\0START|END\0' '
length($0) {printf "START%s\n", $0 > ("folder/demo"++i".txt")}
' demo.txt
RS='\0START|END\0'
定义一个充当 [input] Record Separator 的正则表达式,它将输入文件按\0START
和{{1}之间的字符串(字节序列)分成记录(END\0
代表\0
(null char。)here。
NUL
支持它(一般情况下awk
,但似乎没有mawk
字符。)。NUL
可确保仅在记录非空length($0)
)。
{...}
将{printf "START%s\n", $0 > ("folder/demo"++i)}
前面的每个非空记录输出到文件"START"
,其中folder/demo{n}.txt"
表示以{n}
开头的序列号。答案 2 :(得分:0)
我会将空值转换为换行符,以便grep
可以在一条干净的行上找到您想要的文本:
tr '\000' '\n' < yourfile.bin | grep "^START"
从那里你可以像以前一样把它带进sed
。