ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

【awk】分割指定字段

2022-07-12 15:05:37  阅读:154  来源: 互联网

标签:FIELDWIDTHS 字符 分割 FS FPAT 指定 awk print


https://blog.csdn.net/weixin_45714179/article/details/103224698

 awk  'BEGIN{FIELDWIDTHS="7"}NR>2{print $0,$1}' check_number.txt     分出七位号段

 

 

 

详细分析awk字段分割

红尘小说 https://wap.zuxs.net/

awk读取每一条记录之后,会将其赋值给$0,同时还会对这条记录按照预定义变量FS划分字段,将划分好的各个字段分别赋值给$1 $2 $3 $4...$N,同时将划分的字段数量赋值给预定义变量NF。

引用字段的方式

$N引用字段:

  • N=0:即$0,引用记录本身
  • 0<N<=NF:引用对应字段
  • N>NF:表示引用不存在的字段,返回空字符串
  • N<0:报错

可使用变量或计算的方式指定要获取的字段序号。

  1.   awk '{n = 5;print $n}' a.txt
  2.   awk '{print $(2+2)}' a.txt # 括号必不可少,用于改变优先级
  3.   awk '{print $(NF-3)}' a.txt

分割字段的方式

读取record之后,将使用预定义变量FS、FIELDWIDTHS或FPAT中的一种来分割字段。分割完成之后,再进入main代码段(所以,在main中设置FS对本次已经读取的record是没有影响的,但会影响下次读取)。

 

划分字段方式(一):FS或-F

FS或者-F:字段分隔符

  • FS为单个字符时,该字符即为字段分隔符
  • FS为多个字符时,则采用正则表达式模式作为字段分隔符
  • 特殊的,也是FS默认的情况,FS为单个空格时,将以连续的空白(空格、制表符、换行符)作为字段分隔符
  • 特殊的,FS为空字符串""时,将对每个字符都进行分隔,即每个字符都作为一个字段
  • 设置预定义变量IGNORECASE为非零值,正则匹配时表示忽略大小写(只影响正则,所以FS为单字时无影响)
  • 如果record中无法找到FS指定的分隔符(例如将FS设置为"\n"),则整个记录作为一个字段,即$1$0相等
  1.   # 字段分隔符指定为单个字符
  2.   awk -F":" '{print $1}' /etc/passwd
  3.   awk 'BEGIN{FS=":"}{print $1}' /etc/passwd
  4.    
  5.   # 字段分隔符指定为正则表达式
  6.   awk 'BEGIN{FS=" +|@"}{print $1,$2,$3,$4,$5,$6}' a.txt

 

划分字段方式(二):FIELDWIDTHS

指定预定义变量FIELDWIDTHS按字符宽度分割字段,这是gawk提供的高级功能。在处理某字段缺失时非常好用。

用法:

733013-20191123154647498-149120577.png

示例1:

  1.   # 没取完的字符串DDD被丢弃,且NF=3
  2.   $ awk 'BEGIN{FIELDWIDTHS="2 3 2"}{print $1,$2,$3,$4}' <<<"AABBBCCDDDD"
  3.   AA BBB CC
  4.    
  5.   # 字符串不够长度时无视
  6.   $ awk 'BEGIN{FIELDWIDTHS="2 3 2 100"}{print $1,$2,$3,$4"-"}' <<<"AABBBCCDDDD"
  7.   AA BBB CC DDDD-
  8.    
  9.   # *号取剩余所有,NF=3
  10.   $ awk 'BEGIN{FIELDWIDTHS="2 3 *"}{print $1,$2,$3}' <<<"AABBBCCDDDD"
  11.   AA BBB CCDDDD
  12.    
  13.   # 字段数多了,则取完字符串即可,NF=2
  14.   $ awk 'BEGIN{FIELDWIDTHS="2 30 *"}{print $1,$2,NF}' <<<"AABBBCCDDDD"
  15.   AA BBBCCDDDD 2

示例2:处理某些字段缺失的数据。

如果按照常规的FS进行字段分割,则对于缺失字段的行和没有缺失字段的行很难统一处理,但使用FIELDWIDTHS则非常方便。

假设a.txt文本内容如下:

  1.   ID name gender age email phone
  2.   1 Bob male 28 abc@qq.com 18023394012
  3.   2 Alice female 24 def@gmail.com 18084925203
  4.   3 Tony male 21 aaa@163.com 17048792503
  5.   4 Kevin male 21 bbb@189.com 17023929033
  6.   5 Alex male 18 18185904230
  7.   6 Andy female 22 ddd@139.com 18923902352
  8.   7 Jerry female 25 exdsa@189.com 18785234906
  9.   8 Peter male 20 bax@qq.com 17729348758
  10.   9 Steven female 23 bc@sohu.com 15947893212
  11.   10 Bruce female 27 bcbd@139.com 13942943905

因为email字段有的是空字段,所以直接用FS划分字段不便处理。可使用FIELDWIDTHS。

  1.   # 字段1:4字符
  2.   # 字段2:8字符
  3.   # 字段3:8字符
  4.   # 字段4:2字符
  5.   # 字段5:先跳过3字符,再读13字符,该字段13字符
  6.   # 字段6:先跳过2字符,再读11字符,该字段11字符
  7.   awk '
  8.   BEGIN{FIELDWIDTHS="4 8 8 2 3:13 2:11"}
  9.   NR>1{
  10.   print "<"$1">","<"$2">","<"$3">","<"$4">","<"$5">","<"$6">"
  11.   }' a.txt
  12.    
  13.   # 如果email为空,则输出它
  14.   awk '
  15.   BEGIN{FIELDWIDTHS="4 8 8 2 3:13 2:11"}
  16.   NR>1{
  17.   if($5 ~ /^ +$/){print $0}
  18.   }' a.txt

 

划分字段方式(三):FPAT

FS是指定字段分隔符,来取得除分隔符外的部分作为字段。

FPAT是取得匹配的字符部分作为字段。它是gawk提供的一个高级功能。

FPAT根据指定的正则来全局匹配record,然后将所有匹配成功的部分组成$1、$2...,不会修改$0

  • awk 'BEGIN{FPAT="[0-9]+"}{print $3"-"}' a.txt
  • 之后再设置FS或FPAT,该变量将失效

FPAT常用于字段中包含了字段分隔符的场景。例如,CSV文件中的一行数据如下:

Robbins,Arnold,"1234 A Pretty Street, NE",MyTown,MyState,12345-6789,USA

其中逗号分隔每个字段,但双引号包围的是一个字段整体,即使其中有逗号。

这时使用FPAT来划分各字段比使用FS要方便的多。

  1.   echo 'Robbins,Arnold,"1234 A Pretty Street, NE",MyTown,MyState,12345-6789,USA' |\
  2.   awk '
  3.   BEGIN{FPAT="[^,]*|(\"[^\"]*\")"}
  4.   {
  5.   for (i=1;i<NF;i++){
  6.   print "<"$i">"
  7.   }
  8.   }
  9.   '

最后,patsplit()函数和FPAT的功能一样。

检查字段划分的方式

有FS、FIELDWIDTHS、FPAT三种获取字段的方式,可使用PROCINFO数组来确定本次使用何种方式获得字段。

PROCINFO是一个数组,记录了awk进程工作时的状态信息。

如果:

  • PROCINFO["FS"]=="FS",表示使用FS分割获取字段
  • PROCINFO["FPAT"]=="FPAT",表示使用FPAT匹配获取字段
  • PROCINFO["FIELDWIDTHS"]=="FIELDWIDTHS",表示使用FIELDWIDTHS分割获取字段

例如:

  1.   if(PROCINFO["FS"]=="FS"){
  2.   ...FS spliting...
  3.   } else if(PROCINFO["FPAT"]=="FPAT"){
  4.   ...FPAT spliting...
  5.   } else if(PROCINFO["FIELDWIDTHS"]=="FIELDWIDTHS"){
  6.   ...FIELDWIDTHS spliting...
  7.  

 

标签:FIELDWIDTHS,字符,分割,FS,FPAT,指定,awk,print
来源: https://www.cnblogs.com/xincha/p/16470068.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有