一题处理字符串的脚本题,大家帮忙看看

sh/bash/dash/ksh/zsh等Shell脚本
jyc03071216
帖子: 9
注册时间: 2008-09-04 12:31

一题处理字符串的脚本题,大家帮忙看看

#1

帖子 jyc03071216 » 2009-11-07 15:23

一个output.txt文件中是这样的hello <sad 13>time <ksdisi12>over
写一个脚本输出hello time over应该怎么实现?
最好用shell脚本
aerofox
帖子: 1453
注册时间: 2008-05-24 8:30

Re: 一题处理字符串的脚本题,大家帮忙看看

#2

帖子 aerofox » 2009-11-07 19:36

用 sed 方便:

代码: 全选

sed 's/<[^>]*>//g' output.txt
jyc03071216
帖子: 9
注册时间: 2008-09-04 12:31

Re: 一题处理字符串的脚本题,大家帮忙看看

#3

帖子 jyc03071216 » 2009-11-08 14:40

谢谢LS,很强了,sed一点都不会,要好好学学
大家还有没有其他的方法,如不用sed的
头像
wenstream
帖子: 186
注册时间: 2008-06-18 22:02

Re: 一题处理字符串的脚本题,大家帮忙看看

#4

帖子 wenstream » 2009-11-08 15:00

输出 hello time over 的脚本
echo 'hello time over'
:em04
aerofox
帖子: 1453
注册时间: 2008-05-24 8:30

Re: 一题处理字符串的脚本题,大家帮忙看看

#5

帖子 aerofox » 2009-11-08 16:05

代码: 全选

#/bin/bash
shopt -s extglob
( read line; echo "${line//<+([^>])>/}" ) < output.txt
总算没用外部程序,连 cat 都没用,不过我没觉得这么做有什么意义。
jyc03071216
帖子: 9
注册时间: 2008-09-04 12:31

Re: 一题处理字符串的脚本题,大家帮忙看看

#6

帖子 jyc03071216 » 2009-11-08 16:25

呵呵,,好强大,谢谢aerofox
shopt -s extglob及"${line//<+([^>])>/}" 看不懂
不过,aerofox说的也是对了,确实有个sed这么好的工具,无须这么麻烦了
再一次谢谢aerofox!
aerofox
帖子: 1453
注册时间: 2008-05-24 8:30

Re: 一题处理字符串的脚本题,大家帮忙看看

#7

帖子 aerofox » 2009-11-08 16:37

shopt -s extglob 就是让后面的 +([^]*) 有特殊意义。
+([^]*) 表一个或多个除“>” 以外的字符。
"${line//<+([^>])>/}" 就表示把 line 变量中 “//” 后面说明的内容替换为最后一个 “/”后的内容(什么都没有,就是删除了)。line 后用的 “//” 就表示重复查找替换,如果只用一个“/”就只替换一次。不知这么说明白了没有。
man bash 后搜索一下 Parameter Expansion 和 extglob 有以上两项的解释。
jyc03071216
帖子: 9
注册时间: 2008-09-04 12:31

Re: 一题处理字符串的脚本题,大家帮忙看看

#8

帖子 jyc03071216 » 2009-11-09 18:22

哦,基本明白了,谢谢!
我想再问个问题,现在字符串替换明白了
不过今天遇到一个问题,
是这样的:
在一个output.txt文件中,内容是这样的
hello body
  every body
第二行前面空格是两个tab。
我想在第二行every body中插入hello,使得文件变成
hello body
  every hello body
我是这么写的cat output.txt |sed '2c \\t\tevery hello body' > newfile
之后mv newfile output.txt
感觉这样写法,不好,能不能直接插个hello进去
求个好的写法

PS:再次谢谢aerofox
头像
xiooli
帖子: 6956
注册时间: 2007-11-19 21:51
来自: 成都
联系:

Re: 一题处理字符串的脚本题,大家帮忙看看

#9

帖子 xiooli » 2009-11-09 18:29

代码: 全选

awk -F'[<>]' '{print $1,$3,$5}' output.txt
aerofox
帖子: 1453
注册时间: 2008-05-24 8:30

Re: 一题处理字符串的脚本题,大家帮忙看看

#10

帖子 aerofox » 2009-11-09 19:00

jyc03071216 写了:哦,基本明白了,谢谢!
我想再问个问题,现在字符串替换明白了
不过今天遇到一个问题,
是这样的:
在一个output.txt文件中,内容是这样的
hello body
  every body
第二行前面空格是两个tab。
我想在第二行every body中插入hello,使得文件变成
hello body
  every hello body
我是这么写的cat output.txt |sed '2c \\t\tevery hello body' > newfile
之后mv newfile output.txt
感觉这样写法,不好,能不能直接插个hello进去
求个好的写法

PS:再次谢谢aerofox
可以有很多种方法实现你这个特例的结果,但每种方法应用于其它类似文件的结果可能不一样,现在举几个例子,看你文件内容的一般规律是什么:

代码: 全选

sed '/^\t/s/ / hello /' output.txt > newfile  # 以TAB开头,第一个单词前没有空格
sed 's/every/& hello/' output.txt > newfile  # 把 every 换成 every hello
sed '/hello/!s/body/hello &/' output.txt > newfile  # 如果 body 所在的行没有 hello,则把 body 替换为 hello body
jyc03071216
帖子: 9
注册时间: 2008-09-04 12:31

Re: 一题处理字符串的脚本题,大家帮忙看看

#11

帖子 jyc03071216 » 2009-11-09 19:49

9楼
你估计是回答我帖子中的问题,不过答案aerofox在2楼就写的很漂亮了,你那个只是一种特殊情况合用,不过谢谢你的回贴

10楼
aerofox老大,希望你不会介意,呵呵
谢谢你又回复我
我看了你的答案,第三句的写法不太懂,特别是那个!s
不过都是特殊情况,现在我这样问,如果我想实现,在一个文件中的第二行的第一个单词后加上body就像我上面说的,但是其他行是不清楚的(就相当于可能这个文件很大,什么情况都有,就不能用上面的方法判定了),或第一个单词或某个单词用一句话替换,应该怎么写呢。
aerofox
帖子: 1453
注册时间: 2008-05-24 8:30

Re: 一题处理字符串的脚本题,大家帮忙看看

#12

帖子 aerofox » 2009-11-10 0:34

如果你确保第2行的第一个单词前不会有空格(TAB不算),其后面肯定是空格(不是TAB),那么把我给的第一条语句中的地址范围 /^\t/ 改为 2 就可以了。如果不能保证这一点,而是按常规的用空格或TAB隔离,并且行首可能有空白,那么可以:

代码: 全选

sed '2s/[^\t ]\+/& hello
10楼中第三条语句的 ! 应该理解为跟前面结合,不是!s,在/hello/后加!,就表示不带 hello 的行。

代码: 全选

man sed
.........................
Addresses
       Sed commands can be given with no addresses, in which case the command will be executed for all  input
       lines;  with  one address, in which case the command will only be executed for input lines which match
       that address; or with two addresses, in which case the command will be executed for  all  input  lines
       which  match the inclusive range of lines starting from the first address and continuing to the second
       address.  Three things to note about address ranges: the syntax is addr1,addr2  (i.e.,  the  addresses
       are separated by a comma); the line which addr1 matched will always be accepted, even if addr2 selects
       an earlier line; and if addr2 is a regexp, it will not be tested against the line that addr1  matched.

       After  the  address  (or address-range), and before the command, a !  may be inserted, which specifies
       that the command shall only be executed if the address (or address-range) does not match.

       .......................
jyc03071216
帖子: 9
注册时间: 2008-09-04 12:31

Re: 一题处理字符串的脚本题,大家帮忙看看

#13

帖子 jyc03071216 » 2009-11-10 10:40

aerofox老大
sed '2s/[^\t ]\+/& hello
这个我不太懂,[^\t]是表示以tab开头而\+是什么意思我不太懂,如果前面是两个tab也可以这样吗?

还有其实我是想问定位的问题,比如下面的,我想说如果是在第二行第六个单词之后加入hello
比如这样
hello body
hello every body every body every body every body every body
怎么变成
hello body
hello every body every body every hello body every body every body
注意:第二行前面的空是两个tab(如果是一个tab,一个空格会不会一样呢?)

PS:我查看了很多资料,好像sed不能定位一个一个单词,那能不能和awk混用呢?
谢谢aerofox
上次由 jyc03071216 在 2009-11-10 10:45,总共编辑 1 次。
jyc03071216
帖子: 9
注册时间: 2008-09-04 12:31

Re: 一题处理字符串的脚本题,大家帮忙看看

#14

帖子 jyc03071216 » 2009-11-10 10:42

后面的man sed是叫我看man资料吧,可是对英语理解能力比较差,我会努力看看的,呵呵
t3swing
帖子: 1028
注册时间: 2008-11-01 21:42
来自: 树下板凳

Re: 一题处理字符串的脚本题,大家帮忙看看

#15

帖子 t3swing » 2009-11-10 11:21

sed是个编辑器,还是找一个专门的文档看看吧 ,正则替换是最简单的了 ,强大的功能一时半会也学不会
不过会用简单的几个就可以了 ,高深的问题还是上网找找的好
民族的脊梁,是踏实做事的人,非只知道骂街的泼妇。
回复