问题描述:当前文件夹中有a.txt,b.txt,c.txt,d.txt 等文件,且这些txt文件中的某些行包含有关键字《keywords》和《/keywords》,他们之间包含有其他字符串(注:《keywords》和《/keywords》不一定在同统一行)
要求:分别从这些txt文件中将《keywords》。。。《/keywords》中所有字符串原封不动的分别追加到文件夹 ./newfile中的四个文件,即./newfile/a.txt,./newfile/b.txt,./newfile/c.txt,./newfile/d.txt。
比如说a.txt中为:
fdjs sdfsdfs
《keywords》sdkfjsd《/keywords》
aflsdfsd
《keywords》dsdgfsd
dsfd《/keywords》
那么处理后在./newfile/a.txt中保存为:
《keywords》sdkfjsd《/keywords》
《keywords》dsdgfsd
dsfd《/keywords》
跪求高人指点,感激不尽!!!
先以a.txt为例:
awk -v RS="" '{这样就行了。
为了可读性,我将一条awk语句写成了多行。
实际测试结果如下:
解说:
RS=""
将awk的记录分隔符设置为空(默认是换行符),即将整个a.txt文本看做一条记录。
n = split($0,a,"《[^》]+》");
以正则"《[^》]+》"匹配的内容作为分隔符,对文本内容进行分割并将分割结果存入数组a,分割出的数目(数组大小)即为split函数的返回值n。这里暂且不对该正则做过多解释,否则喧宾夺主,有需要请追问,我再补充。
for(i=2;i<n;i+=2)
print "《keywords》"a[i]"《/keywords》"
打印数组下标为偶数的元素并在首尾分别加上关键字标记以还原。数组下标从1开始。
其他文件可作相同处理。如果文件较多,你可以搞个循环去做。这个应该不难。
追问如何循环读取当前文件夹中的所有.txt文件?一直没找到这样的例子。
追答这种应用其实很常见。
for ofile in *.txt
*.txt 就代表当前目录下所有txt文件的一个集合。
*在这里是通配符,shell解释器会将其自动展开。
追问非常感谢,不过还有一些疑问:
如果说a.txt中含有多对关键字(《keywords1》《keywords1》,《keywords2》《keywords2》),且关键字所包含的字符串都追到./newfile/a.txt中,这样改可以吗?
若文件中包含“《》,《/》”这种字符串,你那种写法会过滤他们吗?
要掌握正则表达式需要花一些功夫,可以去看看网上的《正则表达式30分钟入门教程》。
split函数根据正则表达式《[^》]+》分割文本字符串。
[^》] 表示不为》的任意一个字符。
+表示重复前面这个字符1次或多次,*表示重复前面这个字符0次或多次。
因此,若文件中包含“《》,《/》”这种字符串,可以将+改为*。
正则中,由于+和*都具有贪婪的特性,即总是会最大匹配。拿下面这行文本举例来说:
《keywords》sdkfjsd《/keywords》
《.*》或《.+》会匹配整行文本,而《[^》]+》或《[^》]*》就只能匹配《keywords》或《/keywords》。为了防止匹配到后面一个》,所以这里限定了匹配的字符不为》,即[^》]。
慢慢体会吧。
看懂正则可能不是那么难,但要真正掌握却不是短时间的事,我都不敢说我真正掌握了。