免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 4106 | 回复: 12
打印 上一主题 下一主题

[文本处理] AWK多行,不同条件输出不同字段如何处理? [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2015-09-02 10:31 |只看该作者 |倒序浏览
awk单行不同字段已掌握,当处理一段文本,输出不同行的不同字段时怎么处理呢?

例如文本内容如下:
  1. 2015-08-31 15:53:59,383 INFO  -  进入任务:sendTask ZH05
  2. 2015-08-31 15:53:59,384 INFO  -  目标号码:1
  3. 2015-08-31 15:53:59,384 INFO  -  FROM:111,TO:222 BEGIN
  4. 2015-08-31 15:53:59,384 INFO  -  请求长度为:110
  5. 2015-08-31 15:53:59,424 INFO  -  请求状态:200
  6. 2015-08-31 15:53:59,424 INFO  -  返回值为:<?xml version="1.0" encoding="utf-8"?>2|14410076429841410</string>
  7. 2015-08-31 15:53:59,427 INFO  -  返回值解析后为:2|14410076429841410
复制代码
要求输出结果如下:
2015-08-31 15:53:59,ZH05,222,14410076429841410

以逗号分隔
第一列为本段文本的时间取值
第二列为第一行的最后一个字段
第三列为第三行的TO:后面的值
第四列为返回值中的ID(14410076429841410)

多条件对同一行处理比较清楚,怎么对多行使用不同条件,选择性输出呢,还请给个例子,谢谢。

论坛徽章:
95
程序设计版块每日发帖之星
日期:2015-09-05 06:20:00程序设计版块每日发帖之星
日期:2015-09-17 06:20:00程序设计版块每日发帖之星
日期:2015-09-18 06:20:002015亚冠之阿尔艾因
日期:2015-09-18 10:35:08月度论坛发贴之星
日期:2015-09-30 22:25:002015亚冠之阿尔沙巴布
日期:2015-10-03 08:57:39程序设计版块每日发帖之星
日期:2015-10-05 06:20:00每日论坛发贴之星
日期:2015-10-05 06:20:002015年亚冠纪念徽章
日期:2015-10-06 10:06:482015亚冠之塔什干棉农
日期:2015-10-19 19:43:35程序设计版块每日发帖之星
日期:2015-10-21 06:20:00每日论坛发贴之星
日期:2015-09-14 06:20:00
2 [报告]
发表于 2015-09-02 10:50 |只看该作者
回复 1# xiaogui_vip


    这些行之间有什么关系(根据什么关联在一起)?和其他的类似记录如何区分?

论坛徽章:
145
技术图书徽章
日期:2013-10-01 15:32:13戌狗
日期:2013-10-25 13:31:35金牛座
日期:2013-11-04 16:22:07子鼠
日期:2013-11-18 18:48:57白羊座
日期:2013-11-29 10:09:11狮子座
日期:2013-12-12 09:57:42白羊座
日期:2013-12-24 16:24:46辰龙
日期:2014-01-08 15:26:12技术图书徽章
日期:2014-01-17 13:24:40巳蛇
日期:2014-02-18 14:32:59未羊
日期:2014-02-20 14:12:13白羊座
日期:2014-02-26 12:06:59
3 [报告]
发表于 2015-09-02 10:53 |只看该作者
回复 1# xiaogui_vip


$ cat FILE
2015-08-31 15:53:59,383 INFO  -  进入任务:sendTask ZH05
2015-08-31 15:53:59,384 INFO  -  目标号码:1
2015-08-31 15:53:59,384 INFO  -  FROM:111,TO:222 BEGIN
2015-08-31 15:53:59,384 INFO  -  请求长度为:110
2015-08-31 15:53:59,424 INFO  -  请求状态:200
2015-08-31 15:53:59,424 INFO  -  返回值为:<?xml version="1.0" encoding="utf-8"?>2|14410076429841410</string>
2015-08-31 15:53:59,427 INFO  -  返回值解析后为:2|14410076429841410

$ awk '
BEGIN{
OFS=","
}
/进入任务/{
  time = $1" "$2
  sub(/,.+$/, "", time)
  task = $NF
  to = "";
}
match($0,/TO:([^ ]+)/,a){
  to = a[1]
}
/返回值解析后/{
  sub(/^.*[|]/, "", $NF)
  print time, task, to, $NF
}' FILE
2015-08-31 15:53:59,ZH05,222,14410076429841410

   

论坛徽章:
0
4 [报告]
发表于 2015-09-02 10:56 |只看该作者
回复 2# MMMIX


    行之间的关系是这样的:

    其实应该能看出来,这个是一个程序的日志文件,每次程序开始运行,进入sendTask任务,就会输出这样一段的日志,中间不会夹杂其他日志
    如果这段文本的内容作为A的话,完整的日志应该是这样的:
  1.     A
  2.     无任务需要处理
  3.     A
  4.     无任务需要处理
复制代码
要说关联,并没有根据什么关联在一起,只是一次任务处理的完整日志而已。

论坛徽章:
0
5 [报告]
发表于 2015-09-02 11:08 |只看该作者
回复 3# jason680


    前辈能解释一下两个sub分别的意义么?

论坛徽章:
95
程序设计版块每日发帖之星
日期:2015-09-05 06:20:00程序设计版块每日发帖之星
日期:2015-09-17 06:20:00程序设计版块每日发帖之星
日期:2015-09-18 06:20:002015亚冠之阿尔艾因
日期:2015-09-18 10:35:08月度论坛发贴之星
日期:2015-09-30 22:25:002015亚冠之阿尔沙巴布
日期:2015-10-03 08:57:39程序设计版块每日发帖之星
日期:2015-10-05 06:20:00每日论坛发贴之星
日期:2015-10-05 06:20:002015年亚冠纪念徽章
日期:2015-10-06 10:06:482015亚冠之塔什干棉农
日期:2015-10-19 19:43:35程序设计版块每日发帖之星
日期:2015-10-21 06:20:00每日论坛发贴之星
日期:2015-09-14 06:20:00
6 [报告]
发表于 2015-09-02 11:08 |只看该作者
回复 4# xiaogui_vip


    隐含的条件你最好是明确说出来,不要让别人去猜。猜错了你不是浪费别人时间么?

论坛徽章:
0
7 [报告]
发表于 2015-09-02 11:10 |只看该作者
本帖最后由 xiaogui_vip 于 2015-09-02 11:11 编辑

回复 3# jason680


    搜嘎,仔细看了一下,明白了,是因为RS是空格,使用sub格式化了一下。

    谢谢!仔细咀嚼一下~

论坛徽章:
0
8 [报告]
发表于 2015-09-02 11:11 |只看该作者
回复 6# MMMIX


    什么是隐含的条件? 没明白你的意思呢,只是当作单纯的一段文本去处理不好么?

论坛徽章:
145
技术图书徽章
日期:2013-10-01 15:32:13戌狗
日期:2013-10-25 13:31:35金牛座
日期:2013-11-04 16:22:07子鼠
日期:2013-11-18 18:48:57白羊座
日期:2013-11-29 10:09:11狮子座
日期:2013-12-12 09:57:42白羊座
日期:2013-12-24 16:24:46辰龙
日期:2014-01-08 15:26:12技术图书徽章
日期:2014-01-17 13:24:40巳蛇
日期:2014-02-18 14:32:59未羊
日期:2014-02-20 14:12:13白羊座
日期:2014-02-26 12:06:59
9 [报告]
发表于 2015-09-02 11:14 |只看该作者
回复 5# xiaogui_vip

https://www.gnu.org/software/gawk/manual/gawk.html#String-Functions
9.1.3 String-Manipulation Functions

The functions in this section look at or change the text of one or more strings.

....

sub(regexp, replacement [, target])

    Search target, which is treated as a string, for the leftmost, longest substring matched by the regular expression regexp. Modify the entire string by replacing the matched text with replacement. The modified string becomes the new value of target. Return the number of substitutions made (zero or one).

    The regexp argument may be either a regexp constant (/…/) or a string constant ("…"). In the latter case, the string is treated as a regexp to be matched. See Computed Regexps, for a discussion of the difference between the two forms, and the implications for writing your program correctly.

    This function is peculiar because target is not simply used to compute a value, and not just any expression will do—it must be a variable, field, or array element so that sub() can store a modified value there. If this argument is omitted, then the default is to use and alter $0.47 For example:

    str = "water, water, everywhere"
    sub(/at/, "ith", str)

    sets str to ‘wither, water, everywhere’, by replacing the leftmost longest occurrence of ‘at’ with ‘ith’.

    If the special character ‘&’ appears in replacement, it stands for the precise substring that was matched by regexp. (If the regexp can match more than one string, then this precise substring may vary.) For example:

    { sub(/candidate/, "& and his wife"); print }

    changes the first occurrence of ‘candidate’ to ‘candidate and his wife’ on each input line. Here is another example:

    $ awk 'BEGIN {
    >         str = "daabaaa"
    >         sub(/a+/, "C&C", str)
    >         print str
    > }'
    -| dCaaCbaaa

    This shows how ‘&’ can represent a nonconstant string and also illustrates the “leftmost, longest” rule in regexp matching (see Leftmost Longest).

    The effect of this special character (‘&’) can be turned off by putting a backslash before it in the string. As usual, to insert one backslash in the string, you must write two backslashes. Therefore, write ‘\\&’ in a string constant to include a literal ‘&’ in the replacement. For example, the following shows how to replace the first ‘|’ on each line with an ‘&’:

    { sub(/\|/, "\\&"); print }

    As mentioned, the third argument to sub() must be a variable, field, or array element. Some versions of awk allow the third argument to be an expression that is not an lvalue. In such a case, sub() still searches for the pattern and returns zero or one, but the result of the substitution (if any) is thrown away because there is no place to put it. Such versions of awk accept expressions like the following:

    sub(/USA/, "United States", "the USA and Canada")

    For historical compatibility, gawk accepts such erroneous code. However, using any other nonchangeable object as the third parameter causes a fatal error and your program will not run.

    Finally, if the regexp is not a regexp constant, it is converted into a string, and then the value of that string is treated as the regexp to match.

   

论坛徽章:
0
10 [报告]
发表于 2015-09-02 11:17 |只看该作者
回复 9# jason680


    懂你的意思。谢谢
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP