我有来自供应商的多个文件,多达一百万条记录。
这些文件最初来自 Windows 环境,当我们获取它们时,它们在记录中存在由文本字段中间的换行引起的错误分割。
我认为这是由在传输到 Linux 期间被解释为换行的字符引起的,但不确定,因为我们从未见过原始的 Windows 文件。
我需要的是一个例程,该例程将计算行上分隔符的数量,如果低于指定阈值,则删除记录末尾的换行符。例如,我们知道一条记录有 29 列,应该有 28 个“管道”分隔符(“|”),当我们由于错误的换行而获取数据时,我们会得到两条记录,其中一条记录有 10 个字段和 9 个分隔符第二个包含 19 个字段和 18 个分隔符。以下是出于安全原因更改数据的示例:
9999999999|Duck Donald|87|||999999999|9999999999|XX999999|||Z99999|999 Planet Ln|||Trumpet
ville|ZZ|99999||||||ZZ|P|9999999999|F|||
请注意,该行在“Trumpetville”一词上分开。这是因为插入或误译了换行符。再次寻找一个 woutine 来计算分隔符,并在分隔符数量低于指定阈值时删除换行符。
答案1
尝试:
sed -e :1 -e 's/|/|/28;t' -e 'N;s/\n//;t1' < your-file
或者:
awk -F'|' '{while (NF < 29 && (getline nextline) > 0)
$0 = $0 nextline; print}' < your-file
如果文本具有 CRLF Microsoft 行分隔符,您可能需要首先使用 dos2unix 处理文件。
答案2
假设不需要的回车换行数据中确实不是出现在字段的开头,您可以:
替换预期的回车换行在 linux EOL 行的末尾,如果。
这应该发生在管道字符之后。直接或以空格分隔。因此,将字符串“pipe space CRLF”和“pipe CRLF”替换为“pipe space LF”或“pipe LF”
0x7C 0x20 0x0D 0x0A
和0x7C 0x0D 0x0A
到
0x7C 0x20 0x0A
和0x7C 0x0A
现在唯一回车换行其余部分都在数据中。将字符串“CRLF”替换为空格或空值。
0x0D 0x0A
到0x20
编辑:
预期的 EOL 应位于 2 根管道之间。
|数据|回车换行
|数据|
0x7C 0x0D 0x0A 0x7C
答案3
bash脚本
我读到原来的答案并不是您真正想要的。请看下面的脚本。仅当您事先知道输入文件的元素数量时,这才有效:
#!/bin/bash
infile=/home/wokie/duck.txt
outfile=/home/wokie/duck2.txt
# Define the amount of elements/columns in a row
maxelem=28
# Read the file, strip all newline characters and create one big variable
inputOneline=$(cat $infile | dos2unix | tr -d '\n')
count=0
# Read through the variable and split elements
for element in ${inputOneline//|/ }
do
if [ $count -lt $maxelem ]
then
# Write element to outfile while suppresing newline (-n)
echo -n "$element|" >> $outfile
count=$[$count +1]
else
# Write newline to outfile when maximum elements is reached
echo >> $outfile
count=0
fi
done
整个想法是首先删除所有换行符,然后将新文件与换行符放在正确的位置。
DOS2UNIX
该脚本使用了一个名为 dos2unix 的出色工具。通过仅使用文件名作为参数运行 dos2unix,它会自动将输入 (Windows) 文件转换为 unix 格式。
如果使用 -id 参数启动该工具,则会计算 CRLF 出现的次数,例如:
[test@testsystem ~]$ dos2unix -id /home/wokie/test2.txt 5 /home/wokie/test2.txt
在示例文件中出现了 5 次。
您可以在这里找到 dos2unix 工具: https://sourceforge.net/projects/dos2unix/。大多数发行版都提供 dos2unix 作为标准,或者提供使用 apt-get 或 dnf 安装的可能性。