linux - 使用 Linux 脚本在文件中插入定界符

标签 linux bash awk sed

<分区>

我有一个包含大约 100 万行的非定界文本文件。

示例行

1YBL LOYALTY EXT 1000101172019001
2000100101000011512753184907301010614199100919699034659      VIDYA.SAGAR1@bank.IN                                     VIDYA SAGAR                             CROSS                                   BANDRA                                  WM                                      DELHI                         456471
3000000027

在以数字“2”、“1”、“3”(行类型)开头的每一行上,我必须根据字符数插入定界符,即在末尾 0-1、1-20、21-25。 ..等等

如何使用 Linux 脚本执行此操作?

期望的输出

1|YBL LOYALTY EXT |10001|01172019|001
2|00010010100001151|2753|184907301010614199100919699034659      |VIDYA.SAGAR1@bank.IN                                     |VIDYA SAGAR                             |CROSS                                   |BANDRA                                  |WM                                      |DELHI                         |456471
3|000000027

我试过这个命令

perl -ne ' if(/^2/) { @x=(1,19,6,4,3,8,20,60,40,40,40,40,30); $i=0;
       while($i<=$#x) { $s=$x[$i]; $_=~s/(.{$s})/printf("%s|",$1);""/e;$i++ } 
       print "$_"}   if(/^1/) { @x=(1,16,5,8); $i=0;
       while($i<=$#x) { $s=$x[$i]; $_=~s/(.{$s})/printf("%s|",$1);""/e;$i++ } 
       print "$_" }  if(/^3/) { @x=(1); $i=0;
       while($i<=$#x) { $s=$x[$i]; $_=~s/(.{$s})/printf("%s|",$1);""/e;$i++ } 
       print "$_" }'  filename`

输入行

1YBL LOYALTY EXT 1000112102018001
2000100101000002631653184911501010111199100919323739251      VIJAYPANDEY1191@GMAIL.COM                                   VIJAY PANDEY                            PART OF GROUND FLOOR & BASEMENT         SHOPPER STOP SV ROAD ANDHERI WEST       LANDMARK-ERSTWHILE CRASSWORD BOOK STORE MUMBAI                        400058
2000100101000019920453184964321010513199000919878857482      MAKSUDMASTER7775@GMAIL.COM                                  MOHAMAD MAQSHUD MASTER                  H COLLECTION NEW SHIVPURI               GALI NO 1                               NEAR MAKHAN SINGH CHOWK                 LUDHIANA                      141008
2000100101000023500853184923441010913197300919375580888      JAYNTITALA@GMAIL.COM                                        JAYANTIBHAI TADA                        44 KHODIYAR NAGAR B S ABHISHEK          SUDAMA CHOWK                            KHODIYARNAGAR MOTA VARACHHA             SURAT                         395006
3000000066

预期输出

1|YBL LOYALTY EXT |10001|12102018|001
2|0001001010000026316|531849|1150|101|01111991|00919323739251      |VIJAYPANDEY1191@GMAIL.COM                                   |VIJAY PANDEY                            |PART OF GROUND FLOOR & BASEMENT         |SHOPPER STOP SV ROAD ANDHERI WEST       |LANDMARK-ERSTWHILE CRASSWORD BOOK STORE |MUMBAI                        |400058
2|0001001010000199204|531849|6432|101|05131990|00919878857482      |MAKSUDMASTER7775@GMAIL.COM                                  |MOHAMAD MAQSHUD MASTER                  |H COLLECTION NEW SHIVPURI               |GALI NO 1                               |NEAR MAKHAN SINGH CHOWK                 |LUDHIANA                      |141008
2|0001001010000235008|531849|2344|101|09131973|00919375580888      |JAYNTITALA@GMAIL.COM                                        |JAYANTIBHAI TADA                        |44 KHODIYAR NAGAR B S ABHISHEK          |SUDAMA CHOWK                            |KHODIYARNAGAR MOTA VARACHHA             |SURAT                         |395006
3|000000066

得到这个但是

1|YBL LOYALTY EXT |10001|12102018|001
2|0001001010000026316|531849|1150|101|01111991|00919323739251      |VIJAYPANDEY1191@GMAIL.COM                                   |VIJAY PANDEY                            |PART OF GROUND FLOOR & BASEMENT         |SHOPPER STOP SV ROAD ANDHERI WEST       |LANDMARK-ERSTWHILE CRASSWORD BOOK STORE |MUMBAI                        |400058
2|0001001010000199204|531849|6432|101|05131990|00919878857482      |MAKSUDMASTER7775@GMAIL.COM                                  |MOHAMAD MAQSHUD MASTER                  |H COLLECTION NEW SHIVPURI               |GALI NO 1                               |NEAR MAKHAN SINGH CHOWK                 |LUDHIANA                      |141008
1|41008|
2|0001001010000235008|531849|2344|101|09131973|00919375580888      |JAYNTITALA@GMAIL.COM                                        |JAYANTIBHAI TADA                        |44 KHODIYAR NAGAR B S ABHISHEK          |SUDAMA CHOWK                            |KHODIYARNAGAR MOTA VARACHHA             |SURAT                         |395006
3|95006
3|000000066

最佳答案

对于 FIELDWIDTHS 使用 GNU awk:

$ awk -v FIELDWIDTHS='1 17 4 *' -v OFS='|' '/^2/{$1=$1; gsub(/\s+/,"&"OFS)} 1' file
1YBL LOYALTY EXT 1000101172019001
2|00010010100001151|2753|184907301010614199100919699034659      |VIDYA.SAGAR1@bank.IN                                     |VIDYA |SAGAR                             |CROSS                                   |BANDRA                                  |WM                                      |DELHI                         |456471
3000000027

FIELDWIDTHS 的上述用法表示输入应被视为分为宽度为 1 个字符、17 个字符、4 个字符和其余宽度的 4 个字段。

当您为字段赋值时,awk 会重新编译记录,将输入字段分隔符替换为 OFS 的值,因此 $1=$1 导致 | 被插入到描述的每个字段之间字段宽度。

一旦完成,仍然有所有剩余的空格分隔文本来添加字段分隔符,因此 gsub() 在每一系列空格后附加一个 OFS。

旧版本的 gawk 不支持 * 表示 行的其余部分 - 如果您遇到这种情况,只需替换 *具有较大的值,例如 99999

关于linux - 使用 Linux 脚本在文件中插入定界符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54985113/

相关文章:

linux - 如何在 Ubuntu 服务器上连续运行 go 应用程序

linux - v4l2-ctl - 视频长度和流计数

linux - 创建一个分离 screen ,向它发送命令

linux - jq 是否可以在设置新值时使用已删除的值?

python os.system 命令跳过与命令中的 awk 关联的空格 ""

c++ - 使用 epoll 边缘触发时套接字上的数据过多

android - SQLite UPDATE 值与行号可能/选项?

linux - bash 在此 ssh 命令中做了什么?

linux - 如何使用 awk 中的文本来 cat 系统 ("pwd") 的输出?

bash - awk:从完整路径中提取文件名