正则表达式的应用

需求:

下面一段文本中保存着用户的信息,其中第7个字段是身份证信息,有15位和18位之分,将其中的年份替换成11(15位)或者1111(18位)。环境linux,unix

 

xx|xx|xx|xx|xx|xx|310108900718023|xx|xx|.....
xx|xx|xx|xx|xx|xx|522529198802252219|xx|xx|.....

xx|xx|xx|xx|xx|xx|310108900718023|xx|xx|.....
xx|xx|xx|xx|xx|xx|522529198802252219|xx|xx|..

 

linux环境下,首先想到的方案是:遍历每一行,通过“|”截取,找到身份证后,再通过正则匹配替换。

由于linux中使用正则还需要转义,比如“()”,需要转义成“\(\)”,并没有找到能正确表示"|"的方式,我也尝试了“\|”,但是系统还是认为"|"为特殊字符,于是使用了下面方法:

#!/bin/bash
file='test.txt'
n=0
cat $file | while read line
do
	n=$n+1
	if [ ${#line} == 0 ]
	then
		continue
	else
		i=0
		newline=""
		while((1==1))
		do
			i=$i+1
			split=`echo $line|cut -d "|" -f$i`
			if [ "$split" != "" ]
			then
				if [ $i == 7 ]
				then
					if [ ${#split} == "15" ]
						then
						split=`echo $split | sed 's/\([0-9]\{6\}\)\([0-9]\{2\}\)\([0-9]\{7\}\)/\111\3/g'`
						newline="${newline}${split}|"
					elif  [ ${#split} == "18" ]
						then
						split=`echo $split | sed 's/\([0-9]\{6\}\)\([0-9]\{4\}\)\([0-9]\{8\}\)/\11111\3/g'`
						newline="${newline}${split}|"
					else
						newline="${newline}${split}|"
						continue
					fi
				else
					newline="${newline}${split}|"
					continue
				fi
			else
				newline=`echo ${newline%?}`
				echo newline
				sed "y/${line}/${newline}/" $file    
				break
			fi
		done
	fi
done
echo "success"

后来仔细研究了sed命令,发现linux sed操作有-r,即可扩展的正则表达式,对于"()"不需要进行转义,"\|"也正好能被sed识别,于是解决方式就变简单了:

 

sed -r -i "s/((\w+\|){6})([0-9]{6})([0-9]{2})([0-9]{7})\|/\1\311\5\|/g" test.txt
sed -r -i "s/((\w+\|){6})([0-9]{6})([0-9]{4})([0-9]{8})\|/\1\31111\5\|/g" test.txt

 

实现了方法,但是悲剧的是UNIX系统不支持linux系统很多命令操作。比如sed -r -i都是没有的。而且有些语法不同,所以又回到了原先的方式,去遍历文件再修改,代码如下:

#!/bin/bash
file='test.txt'
newfile='test.bak'
mv $file $newfile
touch $file
text=""
n=0
lastline=`awk '{print NR}' $newfile|tail -n1`
cat $newfile | while read line
do
	n=`expr $n + 1`
	newline=""
	OLD_IFS="$IFS" 
	IFS="|" 
	arr=($line) 
	IFS="$OLD_IFS" 
	i=0
	for s in ${arr[@]}  
	do 
		i=`expr $i + 1`
		len=`expr length $s`
		if [ $i == 7 ]
		then
			if [ $len == "15" ]
			then
				s=`echo $s | sed 's/\([0-9]\{6\}\)\([0-9]\{2\}\)\([0-9]\{7\}\)/\111\3/g'`
				newline="${newline}${s}|"
			elif  [ $len == "18" ]
				then
				s=`echo $s | sed 's/\([0-9]\{6\}\)\([0-9]\{4\}\)\([0-9]\{8\}\)/\11111\3/g'`
				newline="${newline}${s}|"
			else
				newline="${newline}${s}|"
				continue
			fi
		else
			newline="${newline}${s}|"
			continue
		fi
	done 
	newline=`echo ${newline%?}`
	echo $newline >> $file 
done

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值