BASH - 通过附加行修复CSV

时间:2016-01-06 10:45:43

标签: bash csv

目前我有一个包含地址信息的CSV文件,我遇到的问题是地址字段嵌入了新的行字符,因此当我尝试将其加载到MySQL时它不起作用。

以下是我的csv文件的示例:

validators.en.yml

以下是我想要的样子:

ID|NAME|ADDRESS|PHONE
1|"JOHN DOE"|"1 SHORT ROAD LONDON UNITED KINGDOM"|"01234 567 890"
2|"JANE DOE"|"1 SHORT ROAD LONDON 
UNITED KINGDOM"|"01234 567 890"
3|"BOB DOE"|"1
SHORT ROAD
LONDON
UNITED KINGDOM"|"01234 567 890"

我最初的做法是计算' |'在标题行中,并将其作为目标计数。

ID|NAME|ADDRESS|PHONE
1|"JOHN DOE"|"1 SHORT ROAD LONDON UNITED KINGDOM"|"01234 567 890"
2|"JANE DOE"|"1 SHORT ROAD LONDON UNITED KINGDOM"|"01234 567 890"
3|"BOB DOE"|"1 SHORT ROAD LONDON UNITED KINGDOM"|"01234 567 890"

然后我想要做的是逐行遍历文件,在每一行上执行相同的计数

typeset -i target
target=`head -1 broken.csv | awk -F\| '{print NF-1}'`

但是我无法弄清楚下一位的代码

我想做的是

while read -r line
do
count=`echo $line | awk -F\| '{print NF-1}'`

我想我需要一个嵌套循环,但我无法弄清楚语法,所以希望有人能给我一些见解。

任何帮助非常感谢:)

5 个答案:

答案 0 :(得分:0)

一种方法是删除未跟'<ID>|"'(或EOF)的换行符,使用否定的预见断言(由perlpython支持等):

perl -0pe 's/\n(?!(\d+\|"|\z))//g' file

答案 1 :(得分:0)

请查看我对您问题的评论。但是,如果你想坚持自己的修复方式,那就应该做你需要的事情:

cat not-really-broken.csv |sed -e ':a;N;$!ba;s/\([^"]\)\n/\1 /g' -e 's/ /\n/'

主要想法是将所有\n替换为(空格),但前提是它不在"之后,并跳过第一行。

请注意,对于其他一些CSV文件,这可能会失败,因为这些文件可能会使用不同的字符进行引用或在某些字段中省略它。

参考文献:

Have sed make substitute on string but SKIP first occurrence

How can I replace a newline (\n) using sed?

What regex will match every character except comma ',' or semi-colon ';'?

答案 2 :(得分:0)

您可以使用tr命令从文件中删除所有换行符。 removing new line character from incoming stream using sed

cat address_leveling.dat|tr -d '\n' > address_leveling2.dat

然后使用sed搜索模式'一个或多个数字后跟|和“然后将其发送到第三个文件。

sed -e 's/[0-9]\{1,\}|"/\'$'\n&/g' address_leveling2.dat

并手动删除第一个空行。

答案 3 :(得分:0)

#awk -F\| ...
{ fc += NF; s += sep $0; sep = " " }
fc == 4 { print s; fc = 0; s = ""; sep = "" }

累积字段直到达到4。打印并重置。如有必要,请更改sep以留下换行符所在的标记。

答案 4 :(得分:0)

这是一个适用于OSX的解决方案:

>>> a.flatten().tolist()
[1.16179327, -0.1721163]

策略是用空格替换所有换行符,然后在模式sed -e ':a' -e 'N' -e '$!ba' -e 's/\n/ /g' -e 's/\([0-9][0-9]*|\)/\'$'\n\\1/g' testfile.csv 之前插入换行符(数字后跟管道)。

如果您不在OSX上,代码看起来会更清晰(但我现在无法对此进行测试):

number|

实际上,这与pawel7318的解决方案几乎相同。除了由于怪癖而无法在OSX上工作(见OSX sed newlines - why conversion of whitespace to newlines works, but newlines are not converted to spaces)。