这个有点麻烦,需要关联上下行的两个条件。
方法1:
大致思路如下:
按行读取文件,存入数组。
以循环方式按顺序处理数组中的数据。
循环内判断行是否已abc开头,如果是则将变量存入临时变量,并不做输出处理;如果不是abc开头则直接输出变量内容到文件,进入下次循环
再次循环时,判断上一行是否是abc开头,如果是再判断本次的变量结尾是否是def。
如果条件不满足则先输出上一次循环变量(在临时变量内。)到文件,在输出本次循环的变量,临时变量清空,进入下次循环
如果条件满足,则输出duoyu字串到文件两行。
代码如下:
#!/bin/bash
f1=2
f2=""
f3=""
f4=""
while read line
do
echo $line
if [ $f1 -eq 1 ]; then
#preline header include abc
f1=2
f3=${line: -3}
f3=${f3}x
f4=""
if [ $f3 == "defx" ]; then
#line tail include def
echo "duoyu\n" >> s3.txt
echo "duoyu\n" >> s3.txt
else
echo $f2 >> s3.txt
echo $line >> s3.txt
fi
else
f4=${line:0:3}
f4=x$f4
if [ $f4 == "xabc" ]; then
f2=$line
f1=1
else
echo $line >>s3.txt
fi
fi
done < s1.txt
echo $line
if [ $f1 -eq 1 ]; then
echo $f2 >> s3.txt
f2=""
f1=2
fi
代码简略说明:
f4=${line:0:3}
f4=x$f4
变量f4用于判断头部是否是abc,这里给头部加了一个字母x,为了避免刚好取得的3个字符是纯数字。
变量f3也是类似的思路。
-------------------------------------------------------
上面的代码理由漏洞。
第一个漏洞是对文件输入文件s1.txt和输出王文建s3.txt未做相应处理。
应该在头部先判断s1存在和不存在,并做处理。
对s3.txt直接清空即可。
第二个漏洞是在判断上一个循环变量头部包含abc,本次循环变量未包含def的情况,应对本次循环进行是否头部包含abc的检测,并做处理。
#!/bin/bash
> s3.txt
if [ -f s1.txt ]; then
echo "starting..."
else
echo "error!need s1.txt!"
exit 1
fi
f1=2
f2=""
f3=""
f4=""
while read line
do
echo $line
if [ $f1 -eq 1 ]; then
#preline header include abc
f1=2
f3=${line: -3}
f3=${f3}x
f4=""
if [ $f3 == "defx" ]; then
#line tail include def
echo "duoyu\n" >> s3.txt
echo "duoyu\n" >> s3.txt
else
echo $f2 >> s3.txt
f4=${line:0:3}
f4=x$f4
if [ $f4 == "xabc" ]; then
f2=$line
f1=1
else
echo $line >>s3.txt
fi
fi
else
f4=${line:0:3}
f4=x$f4
if [ $f4 == "xabc" ]; then
f2=$line
f1=1
else
echo $line >>s3.txt
fi
fi
done < s1.txt
echo $line
if [ $f1 -eq 1 ]; then
echo $f2 >> s3.txt
f2=""
f1=2
fi
------------------------------
最后做点优化,有一部分代码是重复的,因此稍作调整可以避免重复代码。但是还要增加一个continue
#!/bin/bash
> s3.txt
if [ -f s1.txt ]; then
echo "starting..."
else
echo "error!need s1.txt!"
exit 1
fi
f1=2
f2=""
f3=""
f4=""
while read line
do
echo $line
if [ $f1 -eq 1 ]; then
#preline header include abc
f1=2
f3=${line: -3}
f3=${f3}x
f4=""
if [ $f3 == "defx" ]; then
#line tail include def
echo "duoyu\n" >> s3.txt
echo "duoyu\n" >> s3.txt
continue;
else
echo $f2 >> s3.txt
fi
fi
f4=${line:0:3}
f4=x$f4
if [ $f4 == "xabc" ]; then
f2=$line
f1=1
else
echo $line >>s3.txt
fi
done < s1.txt
echo $line
if [ $f1 -eq 1 ]; then
echo $f2 >> s3.txt
f2=""
f1=2
fi
方法2:
这个用sed直接实现,方法来自某度
sed
'/^abc/{N;/def$/s/.*/douyu/}' s1.txt
方法1和方法2相比方法2比较简洁但是存在瑕疵。如果文件出现如下格式,方法二识别不出来。
abc8888888
abceeeeeeedef
即一行既满足头部abc,也满足尾部def的情况方法2无法识别。