繁体   English   中英

如何从 pipe 分隔文件中归档的数据中删除 Pipe 字符

[英]How to Remove Pipe character from a data filed in a pipe delimited file

专家们,我有一个来自源系统的简单 pipe 分隔文件,它有一个自由流动的文本字段,对于其中一条记录,我看到“|” 字符作为数据的一部分进来。 这不均匀地破坏了我的文件,并且没有被解析为正确的字段数量。 我想替换“|” 在带有“#”的数据字段中。

从源系统传入的记录。 该文件共有 9 个字段。

OutboundManualCall|H|RTYEHLA HTREDFST|Free"flow|Text|20191029|X|X|X|3456

如果您注意到第 4 个字段 - Free"flow|Text,这是来自源的完整值,其中包含 pipe。我想将其更改为 - Free"flow#Text,然后使用 pipe 分隔符读取文件。

期望的结果-

OutboundManualCall|H|RTYEHLA HTREDFST|Free"flow#Text|20191029|X|X|X|3456

我尝试了一些 awk/sed 组合,但没有得到所需的 output。

谢谢

因为你知道有 9 个字段,而第 4 个字段是个问题:取前 3 个字段和后 5 个字段,剩下的就是第 4 个字段。

您确实标记 ,所以这里有一些 bash :我确定 python 等价物很接近:

line='OutboundManualCall|H|RTYEHLA HTREDFST|Free"flow|Text|20191029|X|X|X|3456'
IFS='|'

read -ra fields <<<"$line"
first3=( "${fields[@]:0:3}" )
last5=( "${fields[@]: -5}" )

tmp=${line#"${first3[*]}$IFS"}   # remove the first 3 joined with pipe
field4=${tmp%"$IFS${last5[*]}"}  # remove the last 5 joined with pipe
data=( "${first3[@]}" "$field4" "${last5[@]}" )

newline="${first3[*]}$IFS${field4//$IFS/#}$IFS${last5[*]}"
# .......^^^^^^^^^^^^....^^^^^^^^^^^^^^^^^....^^^^^^^^^^^
printf "%s\n" "$line" "$newline"
OutboundManualCall|H|RTYEHLA HTREDFST|Free"flow|Text|20191029|X|X|X|3456
OutboundManualCall|H|RTYEHLA HTREDFST|Free"flow#Text|20191029|X|X|X|3456

使用 awk,它更简单:如果有 10 个字段,则连接字段 4 和 5,并将 rest 向下移动一位。

echo "$line" | awk '
    BEGIN { FS = OFS = "|" }
    NF == 10 {
        $4 = $4 "#" $5
        for (i=5; i<NF; i++)
            $i = $(i+1)
        NF--
    }
    1
'
OutboundManualCall|H|RTYEHLA HTREDFST|Free"flow#Text|20191029|X|X|X|3456

您用 Python 标记了您的问题,所以我认为基于 Python 的答案是可以接受的。 我假设并非您文件中的所有记录都有额外的“|” 在其中,但只有一些记录有“|” 在自由文本栏中。 对于一个更现实的例子,我创建了一个包含一些正确记录和一些错误记录的输入。

我使用 StringIO 来模拟文件,在您的环境中使用“打开”读取真实文件。

from io import StringIO

sample = 'OutboundManualCall|H|RTYEHLA HTREDFST|Free"flow|Text|20191029|X|X|X|3456\nOutboundManualCall|J|LALALA HTREDFST|FreeHalalText|20191029|X|X|X|3456\nOutboundManualCall|J|LALALA HTREDFST|FrulaalText|20191029|X|X|X|3456\nOutboundManualCall|H|RTYEHLA HTREDFST|Free"flow|Text|20191029|X|X|X|3456'
    
infile = StringIO(sample)
outfile = StringIO()

for line in infile.readlines():
    cols = line.split("|")
    if len(cols) > 9:
        print(f"bad colum {cols[3:5]}")
        line = "|".join(cols[:3]) + "#".join(cols[3:5]) + "|".join(cols[5:])
    outfile.write(line)
print("Corrected file:") 
print(outfile.getvalue())

结果是:

> bad colum ['Free"flow', 'Text']
> bad colum ['Free"flow', 'Text']
> Corrected file:
> OutboundManualCall|H|RTYEHLA HTREDFSTFree"flow#Text20191029|X|X|X|3456
> OutboundManualCall|J|LALALA HTREDFST|FreeHalalText|20191029|X|X|X|3456
> OutboundManualCall|J|LALALA HTREDFST|FrulaalText|20191029|X|X|X|3456
> OutboundManualCall|H|RTYEHLA HTREDFSTFree"flow#Text20191029|X|X|X|3456

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM