请问这样的Shell脚本如何写?

sh/bash/dash/ksh/zsh等Shell脚本
头像
xiajing
帖子: 30
注册时间: 2009-06-10 21:52

Re: 请问这样的Shell脚本如何写?

#31

帖子 xiajing » 2011-08-24 11:25

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命令。
头像
我就是我2
帖子: 1215
注册时间: 2008-12-13 10:55
来自: the Earth
联系:

Re: 请问这样的Shell脚本如何写?

#32

帖子 我就是我2 » 2011-08-24 12:10

可以使用grep

代码: 全选

grep -oP 'begin.*end' file.txt | sed -e 's/^begin//;s/end$//'
不必抓住sed不放.
不过, 处理单行可以,多行不行. :em20
苏东坡问佛印道:“人人皆念观世音菩萨,观世音菩萨念谁?”
佛印答道:“念观世音菩萨。”
苏东坡诧异:“为何亦念观世音菩萨?”
曰:“求人不如求己。”


dropbox 誰好奇,誰來點
勞碌一生又如何,虛度一生又如何,你過得開心嗎?人活著就要開心嘛!
jaszhou
帖子: 7
注册时间: 2011-06-07 8:15

Re: 请问这样的Shell脚本如何写?

#33

帖子 jaszhou » 2011-08-24 13:26

多行文本处理用Perl才是王道,逻辑简单明了。
头像
我就是我2
帖子: 1215
注册时间: 2008-12-13 10:55
来自: the Earth
联系:

Re: 请问这样的Shell脚本如何写?

#34

帖子 我就是我2 » 2011-08-24 15:22

jaszhou 写了:多行文本处理用Perl才是王道,逻辑简单明了。
现在我不是不会么。如你所说的,我还在这折腾sed grep哦。 :em20
如果是perl,怎么写/? 请赐教。 :em06
苏东坡问佛印道:“人人皆念观世音菩萨,观世音菩萨念谁?”
佛印答道:“念观世音菩萨。”
苏东坡诧异:“为何亦念观世音菩萨?”
曰:“求人不如求己。”


dropbox 誰好奇,誰來點
勞碌一生又如何,虛度一生又如何,你過得開心嗎?人活著就要開心嘛!
头像
xiajing
帖子: 30
注册时间: 2009-06-10 21:52

Re: 请问这样的Shell脚本如何写?

#35

帖子 xiajing » 2011-08-24 15:46

我就是我2 写了:可以使用grep

代码: 全选

grep -oP 'begin.*end' file.txt | sed -e 's/^begin//;s/end$//'
不必抓住sed不放.
不过, 处理单行可以,多行不行. :em20
的确用grep也可以, 思路是用grep的 -n 参数,找到第一个x的行数和最后一个y的行数(用shell的${parameter%%:*}提取行数),得到了两个行数,接着就可以用sed删除第一个行数前和第二个行数后的内容,然后对第一行和最后一行进行处理,不太实用,但可以当作练习。
jaszhou 写了:多行文本处理用Perl才是王道,逻辑简单明了。
赞成使用支持non-greedy match的"Practical Extraction and Report Language"
上次由 xiajing 在 2011-08-24 17:32,总共编辑 1 次。
头像
我就是我2
帖子: 1215
注册时间: 2008-12-13 10:55
来自: the Earth
联系:

Re: 请问这样的Shell脚本如何写?

#36

帖子 我就是我2 » 2011-08-24 15:57

的确用grep也可以, 思路是用grep的 -n 参数,找到第一个x的行数和最后一个y的行数(用shell的${parameter%%:.*}提取行数),得到了两个行数,接着就可以用sed删除第一个行数前和第二个行数后的内容,然后对第一行和最后一行进行处理,不太实用,但可以当作练习。
这方法你也想得出来。 :em20
我最多想到前面说的
标记多行=>转成单行=>还原多行
苏东坡问佛印道:“人人皆念观世音菩萨,观世音菩萨念谁?”
佛印答道:“念观世音菩萨。”
苏东坡诧异:“为何亦念观世音菩萨?”
曰:“求人不如求己。”


dropbox 誰好奇,誰來點
勞碌一生又如何,虛度一生又如何,你過得開心嗎?人活著就要開心嘛!
fnan
帖子: 919
注册时间: 2009-07-01 22:04

Re: 请问这样的Shell脚本如何写?

#37

帖子 fnan » 2011-08-24 21:05

xiajing 写了:
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命令。
kose3@kose3-desktop:~$ cat f3.txt
dsojfdj
jdj begin dhfdkhbegin
jddk end1 dkjfij
ksdj end2 sjdkend3
djlk djkfl
kose3@kose3-desktop:~$ sed -r '/begin/!d;t;s/begin/&\n/;s/[^\n]*\n//;:a;N;$!ba;$s/(.*)end.*/\1/' f3.txt
dhfdkhbegin
jddk end1 dkjfij
ksdj end2 sjdk
kose3@kose3-desktop:~$
#可以啊,要分两次处理而已,还是只要一个进程。
bash不如perl精妙,学不到lisp的皮毛,远不够c++强悍,不过可以用。
头像
我就是我2
帖子: 1215
注册时间: 2008-12-13 10:55
来自: the Earth
联系:

Re: 请问这样的Shell脚本如何写?

#38

帖子 我就是我2 » 2011-08-24 21:55

虽然看了你的说明,感觉还是比较高级的东西.得回去参考一下手册. :em06
sed -r '/begin/!d;t;s/begin/&\n/;s/[^\n]*\n//;:a;N;$!ba;$s/(.*)end.*/\1/' f3.txt
苏东坡问佛印道:“人人皆念观世音菩萨,观世音菩萨念谁?”
佛印答道:“念观世音菩萨。”
苏东坡诧异:“为何亦念观世音菩萨?”
曰:“求人不如求己。”


dropbox 誰好奇,誰來點
勞碌一生又如何,虛度一生又如何,你過得開心嗎?人活著就要開心嘛!
fnan
帖子: 919
注册时间: 2009-07-01 22:04

Re: 请问这样的Shell脚本如何写?

#39

帖子 fnan » 2011-08-25 4:10

这个逻辑很简单:

代码: 全选

sed -rn 's/begin/&\n/;T;           :j;N;$!bj;              $s/[^\n]*\n(.*)end.*/\1/p'  file.txt
       没有begin就读下一行     有begin就合并所有行        提取
bash不如perl精妙,学不到lisp的皮毛,远不够c++强悍,不过可以用。
jaszhou
帖子: 7
注册时间: 2011-06-07 8:15

Re: 请问这样的Shell脚本如何写?

#40

帖子 jaszhou » 2011-08-25 14:26

我就是我2 写了:
jaszhou 写了:多行文本处理用Perl才是王道,逻辑简单明了。
现在我不是不会么。如你所说的,我还在这折腾sed grep哦。 :em20
如果是perl,怎么写/? 请赐教。 :em06
LZ可以参考这段代码:

------------------------------------------
#!/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一下具体的用法。
头像
我就是我2
帖子: 1215
注册时间: 2008-12-13 10:55
来自: the Earth
联系:

Re: 请问这样的Shell脚本如何写?

#41

帖子 我就是我2 » 2011-08-25 15:15

@jaszhou
说明一下
我不是LZ 不要看我发贴多,问题多我就是LZ了. :em20
苏东坡问佛印道:“人人皆念观世音菩萨,观世音菩萨念谁?”
佛印答道:“念观世音菩萨。”
苏东坡诧异:“为何亦念观世音菩萨?”
曰:“求人不如求己。”


dropbox 誰好奇,誰來點
勞碌一生又如何,虛度一生又如何,你過得開心嗎?人活著就要開心嘛!
fnan
帖子: 919
注册时间: 2009-07-01 22:04

Re: 请问这样的Shell脚本如何写?

#42

帖子 fnan » 2011-08-25 18:11

jaszhou 写了:
我就是我2 写了:
jaszhou 写了:多行文本处理用Perl才是王道,逻辑简单明了。
现在我不是不会么。如你所说的,我还在这折腾sed grep哦。 :em20
如果是perl,怎么写/? 请赐教。 :em06
LZ可以参考这段代码:

------------------------------------------
#!/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一下具体的用法。
#不是吧,不能就一句吗?
bash不如perl精妙,学不到lisp的皮毛,远不够c++强悍,不过可以用。
horseinfly
帖子: 9
注册时间: 2011-05-30 3:04

Re: 请问这样的Shell脚本如何写?

#43

帖子 horseinfly » 2011-08-25 22:13

手痒,也试试。
for i in *;do tr '\n' '@' <$i|awk -F"x" '{print $2}'|awk -F"y" '{print $1}' |tr '@' '\n'>$i-1.txt;done



想要一个shell 脚本 动作是:
1.依序读入一个文字档 tex1.txt ~ text9.txt:
tex1.txt 内容:
"abcxdefgaxcdyeafgxyxabefght..."
(文件是多行的
需要判断的关键字x y 可能是跨行)
2.删除档案中第1个x之前的内容(含x删除)

3.删除档案中最後一个y以後的内容(含y删除)

4.取得动作2 3 後所得档案 的 x 和 y 之间的文字 另存新档

得到 t1.txt ~ t9.txt

不知好心人可以帮忙一下吗?
头像
我就是我2
帖子: 1215
注册时间: 2008-12-13 10:55
来自: the Earth
联系:

Re: 请问这样的Shell脚本如何写?

#44

帖子 我就是我2 » 2011-08-25 22:42

手痒,也试试。
for i in *;do tr '\n' '@' <$i|awk -F"x" '{print $2}'|awk -F"y" '{print $1}' |tr '@' '\n'>$i-1.txt;done
:em20 跟我的思路一样的. 多行转化单行,再转化成多行.
分隔符是个大问题.你选的是@, 经过别人指点,我使用 \034
苏东坡问佛印道:“人人皆念观世音菩萨,观世音菩萨念谁?”
佛印答道:“念观世音菩萨。”
苏东坡诧异:“为何亦念观世音菩萨?”
曰:“求人不如求己。”


dropbox 誰好奇,誰來點
勞碌一生又如何,虛度一生又如何,你過得開心嗎?人活著就要開心嘛!
fnan
帖子: 919
注册时间: 2009-07-01 22:04

Re: 请问这样的Shell脚本如何写?

#45

帖子 fnan » 2011-08-26 19:14

我就是我2 写了:
手痒,也试试。
for i in *;do tr '\n' '@' <$i|awk -F"x" '{print $2}'|awk -F"y" '{print $1}' |tr '@' '\n'>$i-1.txt;done
:em20 跟我的思路一样的. 多行转化单行,再转化成多行.
分隔符是个大问题.你选的是@, 经过别人指点,我使用 \034
对,可见字符不可用!(命令没有测试吗?不能用的。)
bash不如perl精妙,学不到lisp的皮毛,远不够c++强悍,不过可以用。
回复