日期:2017-8-15

昨天正好接触了一个sed处理文本的问题,顺便就把这个思路和处理过程记录一下。linux中的sed和awk很强大,对于只能说了解的我来说只能通过不断的学习才能更加熟练,下面实例说明。

1.

原文本 : 文本名:file001

aaa,"bbbb,cccc",ddd

甲,"-- , 冰冰冰",大,小

甲,"-- , ttt",大

e,"ffff,ggg",h

需实现的文本:

aaa,bbbbcccc,ddd

甲,--冰冰冰,大,小

甲,--ttt,大

e,ffffggg,h


从上面两个文本可以看出来是要去掉"" 并且双引号中的逗号也需要去掉,同时需要拼接逗号两边的内容。

思路:1:用sed去掉双引号 

sed 's/"//g' file001
再用sed去掉第二个逗号
sed 's/,//2' file001
所以有:
sed -e 's/"//g' -e 's/,//2' file001

最初可以解决上面的要求,但是如果引号所在的域不是都在同一个域内,不在第二个域内就会有问题了。ps:域可以说是列,按照逗号分隔的列。


2.原文本 file002

aaa,"bbbb,cccc",ddd

甲,"## , 冰冰冰",大,小

甲,"##, ttt",大

e,"ffff,ggg",h

bbb,xxx,"sssc,xxx",fff


此时再用上面的解决方法是有问题的,所以另开思路:

思路2:把""中的格式看成"a,b",我们要实现的结果是取出ab 删掉其他东西。此时需要用到 \1\2

方法:sed -r '/".+,.+"/s#"([^ ]+) *, *([^ ]+)"#\1\2#' file002  

1.-r, --regexp-extended  扩展正则

use extended regular  expressions  in  the script.

2. /".+,.+"/ 匹配"a,b" 这个模式

3.([^ ]+)  [^ ]+ 表示非空,^在[]里面表示取反,在外面表示开头,+表示多个 用() 是为了后面的\1 \2   可以存储9个从1-9

4.* 表示0个或者多个


下面是可以其他实现的方法:

  1. sed  's/[ \t]//g' xxx |sed -r 's#"([^ ]+),([^ ]+)"#\1\2#' file002

  2. sed -r 's#"([^ ]+) *, *([^ ]+)"#\1\2#'


相关sed:

sed基本命令

sed英文版