Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/perl/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Perl 将嵌入逗号的CSV文件按行高效地转换为bash数组_Perl_Bash_Shell - Fatal编程技术网

Perl 将嵌入逗号的CSV文件按行高效地转换为bash数组

Perl 将嵌入逗号的CSV文件按行高效地转换为bash数组,perl,bash,shell,Perl,Bash,Shell,通常,我会做类似的事情 IFS=',' columns=( $LINE ) 其中$LINE是我正在读取的csv文件中的一行 但是,如何处理嵌入逗号的csv文件?我必须处理几百gig的文件,所以所有的事情都需要快速完成,也就是说,没有一行的多次读取,绝对没有循环(上次我试过这样做时,有几个因素降低了速度) 守则的一般结构如下: FILENAME=$1 cat $FILENAME | while read LINE do IFS="," columns=( $LINE )

通常,我会做类似的事情

IFS=','
columns=( $LINE )
其中$LINE是我正在读取的csv文件中的一行

但是,如何处理嵌入逗号的csv文件?我必须处理几百gig的文件,所以所有的事情都需要快速完成,也就是说,没有一行的多次读取,绝对没有循环(上次我试过这样做时,有几个因素降低了速度)

守则的一般结构如下:

FILENAME=$1
cat $FILENAME | while read LINE
do
    IFS=","
    columns=( $LINE )
    # affect columns changes here
    newline="${columns[*]}"
    echo "$newline"
done
最好是,我需要一些

FILENAME=$1
cat $FILENAME | while read LINE
do
    IFS=","
    # code to tell bash to ignore if IFS is within an open quote
    columns=( $LINE )
    # affect columns changes here
    newline="${columns[*]}"
    echo "$newline"
done

任何提示都将不胜感激。否则,我可能会转而使用另一种语言来处理这些问题。

这不是一个完整的答案,但这是一种可能的方法

查找输入文件中从未出现过的字符。使用C程序解析CSV文件,并使用不同的分隔符将行打印到标准输出。编写该程序只是一个练习,但我确信还有CSV解析C源代码。将C程序的输出导入脚本

例如:

FILENAME=$1
new_c_program $FILENAME | while read LINE
do
    IFS="|"
    # code to tell bash to ignore if IFS is within an open quote
    columns=( $LINE )
    # affect columns changes here
    newline="${columns[*]}"
    echo "$newline"
done
一个小问题:我会选择一个名字而不是
$newline
<代码>换行符表示行结束标记,而不是整行

另一个小问题:你的问题中的代码中有一个错误。您可以替换此:

cat $FILENAME | while read LINE
do
    ...
done
据此:

while read LINE
do
     ...
done < $FILENAME
读取行时
做
...
完成<$FILENAME

但是如果你用我建议的假想的C程序代替猫,你仍然需要管道。

这不是一个完整的答案,但它是一种可能的方法

查找输入文件中从未出现过的字符。使用C程序解析CSV文件,并使用不同的分隔符将行打印到标准输出。编写该程序只是一个练习,但我确信还有CSV解析C源代码。将C程序的输出导入脚本

例如:

FILENAME=$1
new_c_program $FILENAME | while read LINE
do
    IFS="|"
    # code to tell bash to ignore if IFS is within an open quote
    columns=( $LINE )
    # affect columns changes here
    newline="${columns[*]}"
    echo "$newline"
done
一个小问题:我会选择一个名字而不是
$newline
<代码>换行符表示行结束标记,而不是整行

另一个小问题:你的问题中的代码中有一个错误。您可以替换此:

cat $FILENAME | while read LINE
do
    ...
done
据此:

while read LINE
do
     ...
done < $FILENAME
读取行时
做
...
完成<$FILENAME

但是如果你用我建议的假想的C程序替换了猫,你仍然需要管道。

你可以使用sed或类似的东西将引号中的逗号转换成其他的序列或标点符号。如果你不在乎引号里的东西,你甚至不需要把它们改回去。您可以对整个文件执行此操作:

sed 's/\("[^,"]*\),\([^"]*"\)/\1;\2/g' input.csv > intermediate.csv
或在每行上:

line=$(echo $line | sed 's/\("[^,"]*\),\([^"]*"\)/\1;\2/g')

您可以使用sed或类似的方法将引号中的逗号转换为其他序列或标点符号。如果你不在乎引号里的东西,你甚至不需要把它们改回去。您可以对整个文件执行此操作:

sed 's/\("[^,"]*\),\([^"]*"\)/\1;\2/g' input.csv > intermediate.csv
或在每行上:

line=$(echo $line | sed 's/\("[^,"]*\),\([^"]*"\)/\1;\2/g')
可能嵌入的逗号只是解析这些CSV文件时遇到的第一个明显问题

未来可能出现的问题有:

  • 嵌入的换行符分隔符
  • 嵌入式utf8字符
  • 空格空字段逗号周围空格未定义值的特殊处理
我通常倾向于遵循这样的理念,即如果有一个(声誉良好的)模块可以解析一些 您必须解析的格式,使用它而不是自制

我认为bash没有这样的功能,但是对于Perl有一些功能。我会去的。我希望用C编写会非常快。

可能嵌入的逗号只是解析这些CSV文件时遇到的第一个明显问题

未来可能出现的问题有:

  • 嵌入的换行符分隔符
  • 嵌入式utf8字符
  • 空格空字段逗号周围空格未定义值的特殊处理
我通常倾向于遵循这样的理念,即如果有一个(声誉良好的)模块可以解析一些 您必须解析的格式,使用它而不是自制


我认为bash没有这样的功能,但是对于Perl有一些功能。我会去的。由于是用C语言编写的,我希望它会非常快。

谢谢你的猫提示。我不知道。顺便说一句,示例代码替换不起作用@saccharine:Ah,是的,你是对的(我应该在发布之前尝试一下)。引用链接消息:“不允许在复合命令(如while)前面放置重定向。重定向必须始终出现在复合命令的末尾。重定向只能出现在简单命令中的任何位置。”感谢cat提示。我不知道。顺便说一句,示例代码替换不起作用@saccharine:Ah,是的,你是对的(我应该在发布之前尝试一下)。引用链接消息:“不允许在复合命令(如while)前面放置重定向。重定向必须始终出现在复合命令的末尾。重定向只能出现在简单命令中的任何位置。”您能否详细解释sed命令的作用?我不太熟悉使用reg ex,你的顺序让我很困惑。即使打开wiki页面,我也很难解析它。这似乎是最简单的答案,但它增加了一行额外的可读性。我能让它在columns=($LINE)运行的同时运行吗?您能解释一下sed命令的作用吗?我不太熟悉使用reg ex,你的顺序让我很困惑。即使打开wiki页面,我也很难解析它。这似乎是最简单的答案,但它增加了一行额外的可读性。我可以让它在列=($LINE)运行的同时运行吗