很精简!!!!!fnan 写了:练习完了,就写个简单的sed多行处理:
sed -r ':a;N;$!ba;$s/(^[^x]*x|y[^y]*$)//g' file.txt
问题是标记x和y是字符可以,如果希望保留第一个begin和最后一个end之间的内容,也就是说x字符换成begin字符串,y换成end字符串,那该怎么写更精简呢?
也许是我没有找到,也许是sed不支持 non greedy match,所以模拟non greedy match 花了3个sed命令。
很精简!!!!!fnan 写了:练习完了,就写个简单的sed多行处理:
sed -r ':a;N;$!ba;$s/(^[^x]*x|y[^y]*$)//g' file.txt
代码: 全选
grep -oP 'begin.*end' file.txt | sed -e 's/^begin//;s/end$//'
现在我不是不会么。如你所说的,我还在这折腾sed grep哦。jaszhou 写了:多行文本处理用Perl才是王道,逻辑简单明了。
的确用grep也可以, 思路是用grep的 -n 参数,找到第一个x的行数和最后一个y的行数(用shell的${parameter%%:*}提取行数),得到了两个行数,接着就可以用sed删除第一个行数前和第二个行数后的内容,然后对第一行和最后一行进行处理,不太实用,但可以当作练习。我就是我2 写了:可以使用grep不必抓住sed不放.代码: 全选
grep -oP 'begin.*end' file.txt | sed -e 's/^begin//;s/end$//'
不过, 处理单行可以,多行不行.
赞成使用支持non-greedy match的"Practical Extraction and Report Language"。jaszhou 写了:多行文本处理用Perl才是王道,逻辑简单明了。
这方法你也想得出来。的确用grep也可以, 思路是用grep的 -n 参数,找到第一个x的行数和最后一个y的行数(用shell的${parameter%%:.*}提取行数),得到了两个行数,接着就可以用sed删除第一个行数前和第二个行数后的内容,然后对第一行和最后一行进行处理,不太实用,但可以当作练习。
标记多行=>转成单行=>还原多行
kose3@kose3-desktop:~$ cat f3.txtxiajing 写了:很精简!!!!!fnan 写了:练习完了,就写个简单的sed多行处理:
sed -r ':a;N;$!ba;$s/(^[^x]*x|y[^y]*$)//g' file.txt
问题是标记x和y是字符可以,如果希望保留第一个begin和最后一个end之间的内容,也就是说x字符换成begin字符串,y换成end字符串,那该怎么写更精简呢?
也许是我没有找到,也许是sed不支持 non greedy match,所以模拟non greedy match 花了3个sed命令。
sed -r '/begin/!d;t;s/begin/&\n/;s/[^\n]*\n//;:a;N;$!ba;$s/(.*)end.*/\1/' f3.txt
代码: 全选
sed -rn 's/begin/&\n/;T; :j;N;$!bj; $s/[^\n]*\n(.*)end.*/\1/p' file.txt
没有begin就读下一行 有begin就合并所有行 提取
LZ可以参考这段代码:我就是我2 写了:现在我不是不会么。如你所说的,我还在这折腾sed grep哦。jaszhou 写了:多行文本处理用Perl才是王道,逻辑简单明了。![]()
如果是perl,怎么写/? 请赐教。
#不是吧,不能就一句吗?jaszhou 写了:LZ可以参考这段代码:我就是我2 写了:现在我不是不会么。如你所说的,我还在这折腾sed grep哦。jaszhou 写了:多行文本处理用Perl才是王道,逻辑简单明了。![]()
如果是perl,怎么写/? 请赐教。
------------------------------------------
#!/usr/bin/perl
use strict;
open (my $fh, 'text1.txt') or die "could not open";
open (my $out, '>t1.txt') or die "could not open";
undef $/;
my $line=<$fh>;
print $line;
if($line =~ /start(.*)end/s){
print $1;
print $out $1;
}
close ($fh) or die "error: could not close";
close ($out) or die "error: could not close";
---------------------------------------------------
输入文件text1.txt:
kljljlkjkkldf***start***dfd========start+++++sdfsdfsdfsdf
sdfdsfdfd+++++end======*****end*****sdfdfdsdfdsdfd
输出文件t1.txt:
***dfd========start+++++sdfsdfsdfsdf
sdfdsfdfd+++++end======*****
代码比sed清楚得多。LZ可以google一下具体的用法。
手痒,也试试。
for i in *;do tr '\n' '@' <$i|awk -F"x" '{print $2}'|awk -F"y" '{print $1}' |tr '@' '\n'>$i-1.txt;done
对,可见字符不可用!(命令没有测试吗?不能用的。)我就是我2 写了:手痒,也试试。
for i in *;do tr '\n' '@' <$i|awk -F"x" '{print $2}'|awk -F"y" '{print $1}' |tr '@' '\n'>$i-1.txt;done跟我的思路一样的. 多行转化单行,再转化成多行.
分隔符是个大问题.你选的是@, 经过别人指点,我使用 \034