连接CSV文件

时间:2015-06-29 12:44:08

标签: bash shell csv awk sed

我正在处理CSV文件,其格式如下:

Dates;A;B;C;D;E
"1999-01-04";1391.12;3034.53;66.515625;86.2;441.39
"1999-01-05";1404.86;3072.41;66.3125;86.17;440.63
"1999-01-06";1435.12;3156.59;66.4375;86.32;441

由于我需要在这些数据上实现的BLAS例程只采用双浮点数,我想最简单的方法是在每个字段的末尾连接d0,这样每行看起来像:

"1999-01-04";1391.12d0;3034.53d0;66.515625d0;86.2d0;441.39d0

在伪代码中,那将是:

For every line except the first line
    For every field except the first field
      Substitute ; with d0; and Substitute newline with d0 newline

我的想象力告诉我它应该像

cat file.csv | awk -F; ' NR> 1& NF> 1' {打印行} | sed' s /; / d0 \ n / g' | sed' s / \ n / d0 \ n / g'

任何输入?

5 个答案:

答案 0 :(得分:3)

可以使用此sed

sed '1!{s/\(;[^;]*\)/\1d0/g}' file

跳过第一行,然后将;(跳过第一行)的每个字段替换为自身和d0

输出

Dates;A;B;C;D;E
"1999-01-04";1391.12d0;3034.53d0;66.515625d0;86.2d0;441.39d0
"1999-01-05";1404.86d0;3072.41d0;66.3125d0;86.17d0;440.63d0
"1999-01-06";1435.12d0;3156.59d0;66.4375d0;86.32d0;441d0

答案 1 :(得分:2)

我会说:

$ awk 'BEGIN{FS=OFS=";"} NR>1 {for (i=2;i<=NF;i++) $i=$i"d0"} 1' file
Dates;A;B;C;D;E
"1999-01-04";1391.12d0;3034.53d0;66.515625d0;86.2d0;441.39d0
"1999-01-05";1404.86d0;3072.41d0;66.3125d0;86.17d0;440.63d0
"1999-01-06";1435.12d0;3156.59d0;66.4375d0;86.32d0;441d0

即,将字段分隔符设置为;。从第2行开始,循环遍历附加d0的第2个字段中的所有字段。然后,使用1打印该行。

答案 2 :(得分:2)

您的数据格式看起来有点奇怪。用双引号括起第一列使我认为它可以包含分隔符,分号本身。但是,我不知道生成该数据的应用程序,但如果是这种情况,那么您可以使用以下GNU awk命令:

awk 'NR>1{for(i=2;i<=NF;i++){$i=$i"d0"}}1' OFS=\; FPAT='("[^"]+")|([^;]+)' file

这里的关键是FPAT变量。使用它可以定义字段的外观,而不是仅限于指定一组字段分隔符。

答案 3 :(得分:1)

<强>大prices.csv

Dates;A;B;C;D;E
"1999-01-04";1391.12;3034.53;66.515625;86.2;441.39
"1999-01-05";1404.86;3072.41;66.3125;86.17;440.63
"1999-01-06";1435.12;3156.59;66.4375;86.32;441

预处理脚本

head -n 1 big-prices.csv 1>output.txt; \
tail -n +2 big-prices.csv | \
  sed 's/;/d0;/g' | \
  sed 's/$/d0/g' | \
  sed 's/"d0/"/g' 1>>output.txt;

<强> output.txt的

Dates;A;B;C;D;E
"1999-01-04";1391.12d0;3034.53d0;66.515625d0;86.2d0;441.39d0
"1999-01-05";1404.86d0;3072.41d0;66.3125d0;86.17d0;440.63d0
"1999-01-06";1435.12d0;3156.59d0;66.4375d0;86.32d0;441d0

注意:如果文件在行尾有空格,则必须对第二个sed进行微小的修改。

答案 4 :(得分:1)

使用awk

<强>输入

$ cat file
Dates;A;B;C;D;E
"1999-01-04";1391.12;3034.53;66.515625;86.2;441.39
"1999-01-05";1404.86;3072.41;66.3125;86.17;440.63
"1999-01-06";1435.12;3156.59;66.4375;86.32;441

gsub (任何awk)

$ awk 'FNR>1{ gsub(/;[^;]*/,"&d0")}1' file
Dates;A;B;C;D;E
"1999-01-04";1391.12d0;3034.53d0;66.515625d0;86.2d0;441.39d0
"1999-01-05";1404.86d0;3072.41d0;66.3125d0;86.17d0;440.63d0
"1999-01-06";1435.12d0;3156.59d0;66.4375d0;86.32d0;441d0

gensub (gawk)

$ awk 'FNR>1{ print gensub(/(;[^;]*)/,"\\1d0","g"); next }1' file
Dates;A;B;C;D;E
"1999-01-04";1391.12d0;3034.53d0;66.515625d0;86.2d0;441.39d0
"1999-01-05";1404.86d0;3072.41d0;66.3125d0;86.17d0;440.63d0
"1999-01-06";1435.12d0;3156.59d0;66.4375d0;86.32d0;441d0