linux shell遍历当前文件夹中的txt文件并处理生成新的文件

问题描述:当前文件夹中有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="" '{ 
n = split($0,a,"《[^》]+》");
for(i=2;i<n;i+=2)
    print "《keywords》"a[i]"《/keywords》" 
}' a.txt >>./newfile/a.txt

这样就行了。

为了可读性,我将一条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
do
    awk -v RS="" '{n=split($0,a,"《[^》]+》");for(i=2;i<n;i+=2)print "《keywords》"a[i]"《/keywords》"}' $ofile >>./newfile/$ofile
done

 

*.txt 就代表当前目录下所有txt文件的一个集合。

*在这里是通配符,shell解释器会将其自动展开。

追问

非常感谢,不过还有一些疑问:

如果说a.txt中含有多对关键字(《keywords1》《keywords1》,《keywords2》《keywords2》),且关键字所包含的字符串都追到./newfile/a.txt中,这样改可以吗?

若文件中包含“《》,《/》”这种字符串,你那种写法会过滤他们吗?

追答

要掌握正则表达式需要花一些功夫,可以去看看网上的《正则表达式30分钟入门教程》。
split函数根据正则表达式《[^》]+》分割文本字符串。
[^》] 表示不为》的任意一个字符。
+表示重复前面这个字符1次或多次,*表示重复前面这个字符0次或多次。
因此,若文件中包含“《》,《/》”这种字符串,可以将+改为*。

正则中,由于+和*都具有贪婪的特性,即总是会最大匹配。拿下面这行文本举例来说:
《keywords》sdkfjsd《/keywords》
《.*》或《.+》会匹配整行文本,而《[^》]+》或《[^》]*》就只能匹配《keywords》或《/keywords》。为了防止匹配到后面一个》,所以这里限定了匹配的字符不为》,即[^》]。

慢慢体会吧。
看懂正则可能不是那么难,但要真正掌握却不是短时间的事,我都不敢说我真正掌握了。

温馨提示:内容为网友见解,仅供参考
无其他回答

LINUX下shell 如何将文件夹下的所有txt文件输出到一个txt文件下去
假如在当前面目录下有1.txt和2.txt,现在我们把它输出到3.txt,具体为:!\/bin\/bash echo "start copy file .." find .\/ -name "*.txt" | xargs cat > 3.txt echo "done !" 你那个出问题应该是因为find在查找的时候没有加引号还有后面再查找的时候要使用管道命令啊 ...

linux shell怎么查找文件中指定字符串,并把该字符串和下一行的内容写...
1、grep -i "aaa" -A 1 1.txt | grep -v -e "--" >2.txt grep 指令用于查找内容包含指定的范本样式的文件,如果发现某文件的内容符合所指定的范本样式,预设grep指令会把含有范本样式的那一列显示出来。若不指定任何文件名称,或是所给予的文件名为“-”,则grep指令会从标准输入设备读...

linux遍历文件夹所有文件内容linux遍历文件
1、find命令:find后跟一个存放想要查找的文件的地址,然后后面是-name参数,其后的参数代表文件名称*.jpg就是代表所有的jpg文件了。‘>'符号代表输出到文件,此处输出到制定的txt文件中。2、sed命令:-i代表直接修改读取的文件内容,而非输出到终端 引号中内容代表替换,$代表在文件最后替换,后面跟了一...

如何用shell批量移动子目录下文件到当前文件夹
\/bin\/bashrp=$(pwd)echo rootpath---:${rp}# functionmoveFile(){# get dirsls -F | grep "\/$" > temp_dirs.txtcat temp_dirs.txt | while read d#for d in $(cat temp_dirs.txt);#while read ddocp=$(pwd)\/${d}cd ${cp}echo currentPath---:${cp} ls -al | grep "...

linux shell 遍历文件夹 并将结果保存 到变量
&& echo "$1 not path" && exit 1dir=$1dir_p="$dir Directory :"cd $dirdir=`pwd`for i in `ls $dir`do if [ -d $i ]; then \/tmp\/sh\/dir_file $i #我的脚本文件在\/tmp\/sh中,需要改一下这里 else dir_p="$dir_p File $i" fidonecd ..echo $dir...

linux shell脚本怎么获取目录下所有txt文件名称
执行如下三条命令即可:(1)、$script myresultfile (2)、$ls -al *.txt (3)、$exit 此时,该目录下的所有 txt 文件名称就会以长格式保存在 myresultfile 文件中了。然后你再使用 SHELL 编程的功能把那些无用的列去掉即可。

Linux Shell,遍历数组或文件的几种不同写法
在Linux Shell中,遍历数组或文件的方式有多种,以下是一些常用的方法。首先,关于遍历数组,我们可以使用for循环、while循环结合bash内置变量,以及C风格的for循环。接下来,对于文件遍历,我们可以使用while循环逐行读取文件,利用for循环结合cat命令遍历文件的每一行。然而,需要注意的是,第二种方法在处理...

Linux怎样读取当前文件目录下任意一个文件 不要遍历所有文件,只要获得...
\/bin\/bash ls > txt #将当前目录中的文件名保存到txt echo "该目录中有文件"`head -1 txt` #将目录中的第一个文件名读取出来 rm -rf txt #删除txt文件

Linux虚拟机命令如何创建新的文件和文件夹?
1、首先,连接相应linux主机,进入到linux命令行状态下,等待输入shell指令。2、其次,以文件夹为例,在linux命令行中输入:mkdir newFiler。3、键盘按“回车键”运行shell指令,此时会看到文件夹newFiler被成功创建了。

Linux Shell命令大全(一)——Cat、Chattr、Chgrp命令详解
Linux Shell命令大全(一)——Cat、Chattr、Chgrp命令详解 Linux的Cat命令是查看文件内容和进行流处理的工具,其含义为“concatenate”(连接)。它可以一次性显示整个文件,创建新文件(但不能编辑已有),以及合并多个文件。猫命令的参数如-n或--number用于行号显示,-b或--number-nonblank排除空白行编号...

相似回答