我有一个包含字段的文件,如下所示:
2|508|PNP|20-dec-2015 12:32:20|3451101|0|3xPirate Ship Cruise | CPT||0598
2|504|PNP|20-dec-2015 12:32:20|3451101|0|3xPirate Ship Cruise | CPT||0598
2|505|PNP|20-dec-2015 12:32:20|3451101|0|3xPirate Ship Cruise || CPT||0598
2|506|PNP|20-dec-2015 12:32:20|3451101|0|3xPirate Ship Cruise | |CPT||0598
Run Code Online (Sandbox Code Playgroud)
我想把最终文件归结为:
2|508|PNP|20-dec-2015 12:32:20|3451101|0|3xPirate Ship Cruise CPT||0598
2|504|PNP|20-dec-2015 12:32:20|3451101|0|3xPirate Ship Cruise CPT||0598
2|505|PNP|20-dec-2015 12:32:20|3451101|0|3xPirate Ship Cruise CPT||0598
2|506|PNP|20-dec-2015 12:32:20|3451101|0|3xPirate Ship Cruise CPT||0598
Run Code Online (Sandbox Code Playgroud)
我尝试了以下方法:
sed 's/|//7'
Run Code Online (Sandbox Code Playgroud)
这很棒,因为它删除了不需要的 | 分隔符,但是,在第 7 个字段中,数据有时在第 7 个字段中有超过 1 个管道,我的代码在第一次运行时没有接收到。
有没有办法用 sed、awk 或 python 来删除一个或多个?在第 7 场使总 | 管道总共只有8个|?
您可以使用
sed 's/|[ |]*//7'
Run Code Online (Sandbox Code Playgroud)
这|[ |]*是匹配的 POSIX BRE 模式
| - 一个管道字符[ |]*- 零个或多个空格或管道字符(您也可以[[:blank:]|]*用来匹配任何水平空白或管道字符)。请参阅在线演示:
#!/bin/bash
s='2|508|PNP|20-dec-2015 12:32:20|3451101|0|3xPirate Ship Cruise | CPT||0598
2|504|PNP|20-dec-2015 12:32:20|3451101|0|3xPirate Ship Cruise | CPT||0598
2|505|PNP|20-dec-2015 12:32:20|3451101|0|3xPirate Ship Cruise || CPT||0598
2|506|PNP|20-dec-2015 12:32:20|3451101|0|3xPirate Ship Cruise | |CPT||0598'
sed 's/|[ |]*//7' <<< "$s"
Run Code Online (Sandbox Code Playgroud)
输出:
2|508|PNP|20-dec-2015 12:32:20|3451101|0|3xPirate Ship Cruise CPT||0598
2|504|PNP|20-dec-2015 12:32:20|3451101|0|3xPirate Ship Cruise CPT||0598
2|505|PNP|20-dec-2015 12:32:20|3451101|0|3xPirate Ship Cruise CPT||0598
2|506|PNP|20-dec-2015 12:32:20|3451101|0|3xPirate Ship Cruise CPT||0598
Run Code Online (Sandbox Code Playgroud)
如果您需要匹配到第七个管道字符,然后匹配连续的空格和管道并删除所有管道但保留空格,Perl 解决方案可能更合适:
2|508|PNP|20-dec-2015 12:32:20|3451101|0|3xPirate Ship Cruise CPT||0598
2|504|PNP|20-dec-2015 12:32:20|3451101|0|3xPirate Ship Cruise CPT||0598
2|505|PNP|20-dec-2015 12:32:20|3451101|0|3xPirate Ship Cruise CPT||0598
2|506|PNP|20-dec-2015 12:32:20|3451101|0|3xPirate Ship Cruise CPT||0598
Run Code Online (Sandbox Code Playgroud)
请参阅此在线演示。它的作用是
^(?:[^|]*\|){6}[^|]*\K\|[\s|]*匹配六次出现的零个或多个字符|,然后是一个|字符,然后再匹配零个或多个字符而不是管道(with ^(?:[^|]*\|){6}[^|]*),\K省略匹配的文本并\|[\s|]*匹配并消耗管道字符,然后是任意数量的管道和空白字符e标志,RHS(替换)被视为 Perl 表达式,并且$&=~s/\|//gr意味着g从匹配值中删除所有管道(意味着多次出现)。