2013-04-12 75 views
2

感谢您的阅读。grep/sed:如何打印*东西*什么都没有匹配时

我有一些简单的用户信息

的事情是,有时缺少这些项目中的一个纯文本文件。

通知诺曼和雷吉如何表现的电子邮件地址,但大小姐不会:

Name: Norman Normalrecord 
Email: [email protected] 
Addr: 123 Main street 

Name: Missy Missington 
Addr: 789 Back street 

Name: Reggie Regularrecord 
Email: [email protected] 
Addr: 456 Middle street 

我希望到grep/sed和说:“如果没有找到电子邮件地址,替代与文本missing_email_addr” ,所以我得到这样的结果:

Norman Normalrecord 
[email protected] 
123 main street 

Missy Missington 
MISSING_EMAIL_ADDR 
789 back street 

Reggie Regularrecord 
[email protected] 
456 middle street 

的问题是,在什么时候发现的grep我所有的实验/ SED产生绝对没问题,所以我甚至不能做第二遍全球替换。

我的梦想是什么的是一样的东西(当然伪grep的),它提供了打印的内容时,搜索没有找到任何东西:

grep /Name:/MISSING_NAME/email:/MISSING_EMAIL_ADDR/Addr:/MISSING_STREET_ADDR/ 

有没有办法做这样的事情?再次感谢。

+0

你是否总是在人之间留有空白? –

回答

2

这是一个开始。它用“电子邮件:N/A”替换缺少的电子邮件行。

awk -v RS='\n\n' -v FS='\n' -v OFS='\n' \ 
    '{ if (!$3) $3 = "Email: N/A"; print; print "" }' users.txt 

输出:

Name: Norman Normalrecord 
Email: [email protected] 
Addr: 123 Main street 

Name: Missy Missington 
Addr: 789 Back street 
Email: N/A 

Name: Reggie Regularrecord 
Email: [email protected] 
Addr: 456 Middle street 
0

这里是一个sed脚本似乎做你的 “梦想” 有关(它假定项目与空行分开)什么:

$ cat s.sed 
# collect the lines from one entry in the pattern space 
# removing the empty line for consistency 
:a; $!{N;/\n$/!ba}; s/\n$// 
# make substitutions 
/Name:/!s/^/MISSING_NAME\n/ 
/Email:/!s/\n/\nMISSING_EMAIL_ADDR\n/ 
/Addr:/!s/$/\nMISSING_STREET_ADDR/ 
# add an empty line back 
s/$/\n/p 

您的数据:

$ sed -nf s.sed info.txt 
Name: Norman Normalrecord 
Email: [email protected] 
Addr: 123 Main street 

Name: Missy Missington 
MISSING_EMAIL_ADDR 
Addr: 789 Back street 

Name: Reggie Regularrecord 
Email: [email protected] 
Addr: 456 Middle street 

另一个演示:

$ cat info_ext.txt 
Email: [email protected] 
Addr: 123 Main street 

Name: Missy Missington 
Addr: 789 Back street 

Name: Reggie Regularrecord 
Email: [email protected] 

$ sed -nf s.sed info_ext.txt 
MISSING_NAME 
Email: [email protected] 
Addr: 123 Main street 

Name: Missy Missington 
MISSING_EMAIL_ADDR 
Addr: 789 Back street 

Name: Reggie Regularrecord 
Email: [email protected] 
MISSING_STREET_ADDR 
1

这可能会为你工作(GNU SED):

sed '/^Name: /!b;:a;$!N;/\nAddr: /!ba;/\nEmail: /!s/\n/&Email: MISSING_EMAIL_ADDR&/' file 

如果你想删除的标签:

sed -r '/^Name: /!b;:a;$!N;/\nAddr: /!ba;/\nEmail: /!s/\n/&Email: MISSING_EMAIL_ADDR&/;s/(Name|Email|Addr): //g' file 
1

使用GNU AWK的gensub() :

$ cat tst.awk 
BEGIN { RS=""; ORS="\n\n"; FS=OFS="\n" } 
NF<3 { $3=$2; $2="Email: MISSING_EMAIL_ADDR" } 
{ print gensub(/(^|\n)[^:]+:[[:space:]]*/,"\\1","g") } 

$ gawk -f tst.awk file 
Norman Normalrecord 
[email protected] 
123 Main street 

Missy Missington 
MISSING_EMAIL_ADDR 
789 Back street 

Reggie Regularrecord 
[email protected] 
456 Middle street 

你可以在任何awk中使用sub(/^..)然后gsub(/ \ n ...)而不是gensub(/(^ | \ n)...)来做同样的事情。

万一它是有用的,识别任何缺少的字段,并提供一个“缺失”指示的字段在您的输入中使用,而不必明确命名任何字段的前面(假设每个字段出现在至少一条记录中)将是:

$ cat tst.awk 
BEGIN { RS=""; FS=OFS="\n" } 
{ 
    for (fldNr=1; fldNr<=NF; fldNr++) { 

     split($fldNr,nameVal,/:[[:space:]]*/) 

     name = nameVal[1] 
     val = nameVal[2] 

     rec[NR,name] = val 

     if (!seen[name]++) { 
     for (nameNr=++numNames; nameNr>fldNr; nameNr--) { 
      names[nameNr] = names[nameNr-1] 
     } 
     names[nameNr] = name 
     } 

    } 

} 

END { 
    for (recNr=1; recNr<=NR; recNr++) { 

     for (nameNr=1; nameNr<=numNames; nameNr++) { 

     name = names[nameNr] 
     key = recNr SUBSEP name 

     if (key in rec) { 
      print rec[key] 
     } 
     else { 
      print "MISSING_" toupper(name) 
     } 
     } 

     print "" 

    } 
} 
$ 
$ cat file 
Name: Norman Normalrecord 
Email: [email protected] 
Addr: 123 Main street 

Name: Missy Missington 
Addr: 789 Back street 

Name: Reggie Regularrecord 
Email: [email protected] 
Addr: 456 Middle street 
Whatever: Some useful info 
$ 
$ awk -f tst.awk file 
Norman Normalrecord 
[email protected] 
123 Main street 
MISSING_WHATEVER 

Missy Missington 
MISSING_EMAIL 
789 Back street 
MISSING_WHATEVER 

Reggie Regularrecord 
[email protected] 
456 Middle street 
Some useful info 
相关问题