【问题标题】:Converting text data file to csv format via shell/bash通过 shell/bash 将文本数据文件转换为 csv 格式
【发布时间】:2018-07-10 06:47:35
【问题描述】:

我正在寻找一个简单的控制台解决方案来更改如下所示的文本文件:

...
Gender: M
Age: 46
History: 01305
Gender: F
Age: 46
History: 01306
Gender: M
Age: 19
History: 01307
Gender: M
Age: 19
History: 01308
....

像这样的 csv 文件:

Gender,Age,History
M,46,01305
F,46,01306
M,19,01307
M,19,01308

任何帮助表示赞赏


通过以下解决方案,我收到了此输出。我做错了吗?

awk 'BEGIN{printf "Gender,Age,History%s",ORS;FS=":"}{c++} {sub(/^   */,"",$2);printf "%s%s",$2,(c==3)?ORS:","}c==3{c=0}' data.txt >> 1.csv

Gender,Age,History
M
,37
,00001
M
,37
,00001
M
,41
,00001

【问题讨论】:

  • 到目前为止,您尝试了什么?此外,您会发现很多重复的问题与确切要求:-)
  • 这可能会有所帮助awk 'BEGIN{printf "Gender,Age,History%s",ORS} {FS=":";count++} {sub(/^ */,"",$2);printf "%s%s",$2,(cou nt==3)?ORS:","}count==3{count=0}' file
  • 请注意上面count 中的无意空格。应该删除空格。最好将字段分隔符放在BEGIN 块中,如awk 'BEGIN{printf "Gender,Age,History%s",ORS;FS=":"}{c++} {sub(/^ */,"",$2);printf "%s%s",$2,(c==3)?ORS:","}c==3{c=0}' file
  • @sjsam 你能再看看吗?我尝试了您的解决方案,它有效,但存在一些问题。如果有必要,我正在使用 OSX shell。非常感谢
  • 我对你得到的东西感到困惑,尤其是逗号前的换行符。我不确定这与你使用 OSX 有什么关系。我来研究一下

标签: bash shell csv export-to-csv


【解决方案1】:

这一行应该会有所帮助:

awk 'BEGIN{FS=":|\n";RS="Gender";OFS=",";print "Gender,Age,History"}$0{print $2,$4,$6}' file

以您的示例作为输入,它给出:

Gender,Age,History
 M, 46, 01305
 F, 46, 01306
 M, 19, 01307
 M, 19, 01308

【讨论】:

    【解决方案2】:

    仅使用 bash 内置命令,我会说:

    #!/bin/bash
    
    echo "Gender,Age,History"
    while read line; do
        if [[ $line =~ ^Gender:\ *([^\ ]+) ]]; then
            r=${BASH_REMATCH[1]}
        elif [[ $line =~ ^Age:\ *([^\ ]+) ]]; then
            r+=,${BASH_REMATCH[1]}
        elif [[ $line =~ ^History:\ *([^\ ]+) ]]; then
            echo $r,${BASH_REMATCH[1]}
        fi
    done < data.text
    

    【讨论】:

    • read 没有-r 将破坏反斜杠。还要双引号 $r${BASH_REMATCH[1]} 以防止通配符和分词。
    【解决方案3】:

    这是一种在 bash 中执行此操作的方法。假设您的数据文件名为 data.txt

    #!/bin/bash
    
    echo "Gender,Age,History"
    while read -r line; do
      printf '%s' "$(cut -d ' ' -f2 <<< $line )"
      if [[ "$line" =~ ^History.* ]]; then
        printf "\n"
      else
        printf ","
      fi
    done < data.txt
    

    输出:

    Gender,Age,History
    M,46,01305
    F,46,01306
    M,19,01307
    M,19,01308
    

    【讨论】:

    • 你应该双引号$(cut -d ' ' -f2 &lt;&lt;&lt; $line )。此外,没有-rread 将破坏反斜杠。Here strings: &lt;&lt;&lt; WORD 出现在bash 2.05b-alpha1 中。虽然我们可以很确定 op 会有更高版本的bash
    • 用@sjsam cmets 更新。谢谢:)
    【解决方案4】:

    我还是不知道问题出在哪里 所以我决定清除所有字符的数据,除了那些应该在那里的字符(很可能是不寻常的行尾符号)

    sed -e 's/[^a-zA-Z*0-9:]/ /g;s/  */ /g' history.txt > output.txt
    

    然后成功地使用了@sjsam 的解决方案

    awk 'BEGIN{printf "Gender,Age,History%s",ORS;FS=":"}{c++} {sub(/^   */,"",$2);printf "%s%s",$2,(c==3)?ORS:","}c==3{c=0}' data.txt >> 1.csv
    

    谢谢大家!

    【讨论】:

      猜你喜欢
      • 2019-06-20
      • 1970-01-01
      • 2019-05-08
      • 2013-07-23
      • 2018-07-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-07-01
      相关资源
      最近更新 更多