多行CSV:使用不同的分隔符在单行上输出,带双引号输入行

时间:2017-04-18 23:53:36

标签: bash csv awk multiline

我正试图在Bash中将CSV的多行输出转换为一行。

我的CSV文件如下所示:

hi,bye
hello,goodbye

最终目标是看起来像这样:

"hi/bye", "hello/goodbye"

目前我在这里:

INPUT=mycsvfile.csv
while IFS=, read col1 col2 || [ -n "$col1" ]
do
  source=$(awk '{print;}' | sed -e 's/,/\//g' )
  echo "$source";
done < $INPUT

输出在每一行上,我能够将其更改为/但我不知道如何将输出放在一行上并带有引号。

我试过BEGIN:

source=$(awk 'BEGIN { ORS=", " }; {print;}'| sed -e 's/,/\//g' )

但是这只输出最后一行,并省略了第一个hi / bye:

hello/goodbye

有人能帮助我吗?

7 个答案:

答案 0 :(得分:1)

在awk中完成整个事情(主要是)。最后的sed就是在这里修剪一些尾随并在最后注入一个换行符:

< mycsvfile.csv awk '{print "\""$1, $2"\""}' FS=, OFS=/ ORS=", " | sed 's/, $//'

答案 1 :(得分:1)

如果您愿意安装我的实用程序 trl ,该命令可以简化如下:

input=mycsvfile.csv
trl -R '| ' < "$input" | tr ',|' '/,'
  • trl默认情况下将多行输入转换为由,<space>分隔的双引号单行输出。

    • -R '| '(暂时)使用|<space>作为分隔符;这假设您的数据不包含|个实例,但您可以选择任何字符。您知道不属于您的数据。
  • tr ',|' '/,'然后将所有,个实例(输入行的字段内部)转换为/个实例,以及所有|个实例(临时分隔符)进入,个实例,根据需要产生整体结果。

npm registry(Linux和macOS)

安装trl

注意:即使您不使用Node.js,npm,它的软件包管理器也可以跨平台运行,并且易于安装;尝试
curl -L https://git.io/n-install | bash

安装Node.js后,按如下方式安装:

[sudo] npm install trl -g

注意

  • 是否需要sudo取决于您安装Node.js的方式以及您是否changed permissions later;如果您收到EACCES错误,请使用sudo再次尝试。
  • -g确保global installation,并且需要将trl放入您的系统$PATH

手动安装(任何带有bash的Unix平台)

  • this bash script下载为trl
  • 使用chmod +x trl使其可执行。
  • 将其移动或符号链接到$PATH中的文件夹,例如/usr/local/bin(macOS)或/usr/bin(Linux)。

答案 2 :(得分:1)

$ awk -F, -v OFS='/' -v ORS='"' '{$1=s ORS $1; s=", "; print} END{printf RS}' file
"hi/bye", "hello/goodbye"

答案 3 :(得分:0)

不需要bash循环,这总是很慢。

sedtr可以更有效地执行此操作:

input=mycsvfile.csv
sed 's/,/\//g; s/.*/"&", /; $s/, $//' "$input" | tr -d '\n'
  • s/,/\//g使用g个实例替换所有(,/个实例(此处转义为\/)。

    < / LI>
  • s/.*/"&", /将结果行包含在"..."中,然后是,<space>

    • 正则表达式.*匹配整个模式空间(可能已修改的输入行)
    • 替换字符串中的
    • &表示该匹配。
  • $s/, $//最终行(,<space>

  • 中删除不受欢迎的结尾$
  • tr -d '\n'然后只是从结果中删除换行符(\n),因为sed总是输出每一行的尾随换行符。

请注意,上面命令的单行输出不会有尾随换行符;如果需要,只需添加; printf '\n'

答案 4 :(得分:0)

在awk中:

$ awk '{sub(/,/,"/");gsub(/^|$/,"\"");b=b (NR==1?"":", ")$0}END{print b}' file
"hi/bye", "hello/goodbye"

说明:

$ awk '
{
    sub(/,/,"/")            # replace comma
    gsub(/^|$/,"\"")        # add quotes
    b=b (NR==1?"":", ") $0  # buffer to add delimiters
}
END { print b }             # output
' file

答案 5 :(得分:0)

我假设你的文件中只有2行?如果您有2对线交替,请在评论中告诉我,我将针对该一般情况进行扩展。以下是您的一行Repositories code generation...转换:

awk

输出:

# NOTE: I am using the octal ascii code for the 
# double quote char (\42=") in my printf statement
$ awk '{gsub(/,/,"/")}NR==1{printf("\42%s\42, ",$0)}NR==2{printf("\42%s\42\n",$0)}' file

答案 6 :(得分:0)

这是我在awk中的尝试:

awk 'BEGIN{ ORS = " " }{ a++; gsub(/,/, "/"); gsub(/[a-z]+\/[a-z]+/, "\"&\""); print $0; if (a == 1){ print "," }}{ if (a==2){ printf "\n"; a = 0 } }'

如果您的输入有两行以上,也可以使用。如果您需要一些解释,请随意询问:)