Chinaunix

标题: 请问大神,单用awk能输出与正则表达式匹配的内容吗? [打印本页]

作者: sxingbai    时间: 2017-05-02 20:33
标题: 请问大神,单用awk能输出与正则表达式匹配的内容吗?
如题,好像awk更适合于输出符合条件的行或字段,但如果任意一个正则式,能只从文件中提取相关内容吗?
如能,如果一行中有若干处可匹配的字符串,是只提取第一个还是全都提取?或者有不同的实现方法?
先谢!


作者: yinyuemi    时间: 2017-05-03 08:29
本帖最后由 yinyuemi 于 2017-05-03 08:31 编辑

回复 1# sxingbai

  1. match

  2. gensub
  3. RS->RT
  4. split
复制代码




作者: sxingbai    时间: 2017-05-03 15:49
回复 2# yinyuemi

多谢大神!
不过说得太简略,我再去啃啃阁下所列的这几个函数。

作者: jason680    时间: 2017-05-03 19:27
回复 3# sxingbai

give us the example ...

or

http://bbs.chinaunix.net/thread-2309494-1-1.html

作者: sxingbai    时间: 2017-05-04 15:52
多谢楼上诸位
基本搞明白了
用match返回匹配字符串的起始位置和长度
再用substr调用并输出
作者: jason680    时间: 2017-05-04 16:17
回复 5# sxingbai

try this way and get the data/string eaily ...

$ echo -e "name:john\nage:20\nxxx:yyy" | awk '{if(match($0,"age:([0-9]+)",m)){print m[1]}}'
20


作者: sxingbai    时间: 2017-05-04 17:38
回复 6# jason680

多谢,受教了
数组不仅简洁,也更灵活
再次感谢

作者: sxingbai    时间: 2017-05-05 11:47
回复 6# jason680

抱歉,再麻烦个问题
match函数只能提取一个记录中最左的匹配内容,如果这个记录中还有多处可匹配,如何都提取出来?
我想不出其它办法,觉得好像只能用循环,并把已提取内容置空。
请指教!多谢!

作者: sxingbai    时间: 2017-05-05 18:38
本帖最后由 sxingbai 于 2017-05-05 19:00 编辑

但是如何把已匹配内容置空,却不容易实现,只得用sub置空,感觉很笨
请大神指教
或有没有其它方法
作者: jason680    时间: 2017-05-05 19:54
回复 8# sxingbai

example ?

作者: sxingbai    时间: 2017-05-05 20:10
回复 10# jason680

比如这段文字:
及载登相位,因揆当徙职,遂奏为试秘书监,江淮养疾。既无禄俸,家复贫乏,孀孤百口,丐食取给。萍寄诸州,凡十五六年,其牧守稍薄,则又移居,故其迁徙者,盖十余州焉。元载以罪诛,除揆睦州刺史,入拜国子祭酒、礼部尚书,为卢杞所恶。德宗在山南,令充入蕃贫会盟使,加左仆射。行至凤州,以疾卒,兴元元年四月也,年七十四。(节选自《旧唐书·李揆传》)

想要提取“疾”字所在的句子以及最后括号以其中的内容
目前采用的方法是:
awk '{while(match($0,/([^。?!:]*疾[^。?!:]*)(.+)((.+))/,arr)){print arr[1],arr[3];sub(/([^。?!:]*疾[^。?!:]*)/,"")}}'

抱歉,我不是不举例,只是我更想要通用的方法而不是根据情况通过变更分隔符的方法实现。
再次感谢!

作者: sxingbai    时间: 2017-05-05 20:10
回复 10# jason680

比如这段文字:
及载登相位,因揆当徙职,遂奏为试秘书监,江淮养疾。既无禄俸,家复贫乏,孀孤百口,丐食取给。萍寄诸州,凡十五六年,其牧守稍薄,则又移居,故其迁徙者,盖十余州焉。元载以罪诛,除揆睦州刺史,入拜国子祭酒、礼部尚书,为卢杞所恶。德宗在山南,令充入蕃贫会盟使,加左仆射。行至凤州,以疾卒,兴元元年四月也,年七十四。(节选自《旧唐书·李揆传》)

想要提取“疾”字所在的句子以及最后括号以其中的内容
目前采用的方法是:
awk '{while(match($0,/([^。?!:]*疾[^。?!:]*)(.+)((.+))/,arr)){print arr[1],arr[3];sub(/([^。?!:]*疾[^。?!:]*)/,"")}}'

抱歉,我不是不举例,只是我更想要通用的方法而不是根据情况通过变更分隔符的方法实现。
再次感谢!

作者: sxingbai    时间: 2017-05-05 20:14
回复 10# jason680
比如这段文字:
载衔恨颇深。及载登相位,因揆当徙职,遂奏为试秘书监,江淮养疾。既无禄俸,家复贫乏,孀孤百口,丐食取给。萍寄诸州,凡十五六年,其牧守稍薄,则又移居,故其迁徙者,盖十余州焉。元载以罪诛,除揆睦州刺史,入拜国子祭酒、礼部尚书,为卢杞所恶。德宗在山南,令充入蕃贫会盟使,加左仆射。行至凤州,以疾卒,兴元元年四月也,年七十四。(节选自《旧唐书·李揆传》)

比如要提取“疾”字所在的句子以及最后的括号以及其间的内容,我目前采用的方法是:
awk '{while(match($0,/([^。?!:]*疾[^。?!:]*)(.+)((.+))/,arr)){print arr[1],arr[3];sub(/([^。?!:]*疾[^。?!:]*)/,"")}}'

抱歉,我不是不想举例,而是想知道通用的方法而不是根据文本情况用变更分隔符的方法实现。
再次感谢!


作者: sxingbai    时间: 2017-05-05 20:16
回复 10# jason680
比如这段文字:
载衔恨颇深。及载登相位,因揆当徙职,遂奏为试秘书监,江淮养疾。既无禄俸,家复贫乏,孀孤百口,丐食取给。萍寄诸州,凡十五六年,其牧守稍薄,则又移居,故其迁徙者,盖十余州焉。元载以罪诛,除揆睦州刺史,入拜国子祭酒、礼部尚书,为卢杞所恶。德宗在山南,令充入蕃贫会盟使,加左仆射。行至凤州,以疾卒,兴元元年四月也,年七十四。(节选自《旧唐书·李揆传》)

我这样写:
awk '{while(match($0,/([^。?!:]*疾[^。?!:]*)(.+)((.+))/,arr)){print arr[1],arr[3];sub(/([^。?!:]*疾[^。?!:]*)/,"")}}'

没有举例,主要是不想涉及分隔符,而求得一种通用方法。
多谢!



作者: sxingbai    时间: 2017-05-05 20:17
  1. 比如这段文字:
  2. 载衔恨颇深。及载登相位,因揆当徙职,遂奏为试秘书监,江淮养疾。既无禄俸,家复贫乏,孀孤百口,丐食取给。萍寄诸州,凡十五六年,其牧守稍薄,则又移居,故其迁徙者,盖十余州焉。元载以罪诛,除揆睦州刺史,入拜国子祭酒、礼部尚书,为卢杞所恶。德宗在山南,令充入蕃贫会盟使,加左仆射。行至凤州,以疾卒,兴元元年四月也,年七十四。(节选自《旧唐书·李揆传》)

  3. 我这样写:
  4. awk '{while(match($0,/([^。?!:]*疾[^。?!:]*)(.+)((.+))/,arr)){print arr[1],arr[3];sub(/([^。?!:]*疾[^。?!:]*)/,"")}}'

  5. 没有举例,主要是不想涉及分隔符,而求得一种通用方法。
  6. 多谢!
复制代码

回复 10# jason680



作者: sxingbai    时间: 2017-05-05 20:18
回复 10# jason680

怎么不能回复?

作者: sxingbai    时间: 2017-05-05 20:18
比如这段文字:
载衔恨颇深。及载登相位,因揆当徙职,遂奏为试秘书监,江淮养疾。既无禄俸,家复贫乏,孀孤百口,丐食取给。萍寄诸州,凡十五六年,其牧守稍薄,则又移居,故其迁徙者,盖十余州焉。元载以罪诛,除揆睦州刺史,入拜国子祭酒、礼部尚书,为卢杞所恶。德宗在山南,令充入蕃贫会盟使,加左仆射。行至凤州,以疾卒,兴元元年四月也,年七十四。(节选自《旧唐书·李揆传》)

我这样写:
awk '{while(match($0,/([^。?!:]*疾[^。?!:]*)(.+)((.+))/,arr)){print arr[1],arr[3];sub(/([^。?!:]*疾[^。?!:]*)/,"")}}'

没有举例,主要是不想涉及分隔符,而求得一种通用方法。
多谢!

作者: sxingbai    时间: 2017-05-05 20:21
抱歉,因为传输错误,上传了这么多次
作者: jason680    时间: 2017-05-05 21:03
回复 11# sxingbai

How about this way for 通用的方法 ...

$ awk -f get_xxx.awk FILE
及载登相位,因揆当徙职,遂奏为试秘书监,江淮养疾 (节选自《旧唐书·李揆传》)
行至凤州,以疾卒,兴元元年四月也,年七十四 (节选自《旧唐书·李揆传》)

$ cat get_xxx.awk
function get_char(){
  if(match($0,"((.+))",m)){
    sub("((.+))","")
    return m[1]
  }
  return "";
}
function print_all(str,key,char){
  while(match(str,"([^。?!:]*"key"[^。?!:]*)",m)){
    str = substr(str,RSTART+RLENGTH);
    #sub(key,"<"key">",m[1]);
    print m[1],char;
  }
}
{
  char = get_char();
  print_all($0,"疾",char);
}


作者: sxingbai    时间: 2017-05-05 21:46
回复 19# jason680

多谢!

作者: sditmaner    时间: 2017-05-06 11:00
回复 6# jason680




欢迎光临 Chinaunix (http://bbs.chinaunix.net/) Powered by Discuz! X3.2