【问题标题】:How to create a CSV file based on row in shell script?如何根据 shell 脚本中的行创建 CSV 文件?
【发布时间】:2017-01-09 22:14:33
【问题描述】:

我有一个文本文件 /tmp/some.txt 具有以下值

JOHN              YES     6          6            2345762
 SHAUN             NO     6          6            2345748

我想创建一个具有以下格式的 csv 文件(即基于行。不基于列)。

JOHN,YES,6,6,2345762
SHAUN,NO,6,6,2345748

我试过下面的代码

for i in `wc -l /tmp/some.txt | awk '{print $1}'`
do
awk  'NR==$i' /tmp/some.txt | awk '{print $1","$2","$3","$4","$5}' >> /tmp/some.csv
done

这里wc -l /tmp/some.txt | awk '{print $1}' 将获得值为 2(即文本文件中的 2 行)。 对于每一行,awk 'NR==$i' /tmp/some.txt | awk '{print $1","$2","$3","$4","$5}' 会将 5 个字段打印到 some.csvfile 中,用逗号分隔。

当我分别执行每个命令时,它会起作用。但是当我将它作为一个 shell 脚本时,我得到了空的some.csv 文件。

【问题讨论】:

  • 为什么不用一个逗号替换所有的空格块?

标签: linux bash shell


【解决方案1】:

@Kart:请您尝试关注一下。

awk '{$1=$1;} 1' OFS=,   Input_file  > output.csv

希望对你有帮助。

【讨论】:

    【解决方案2】:

    我建议:

    sed 's/[[:space:]]\+/,/g' /tmp/some.txt
    

    【讨论】:

      【解决方案3】:

      你几乎明白了。 awk 已逐行处理文件,因此您无需使用 for 循环进行迭代。

      所以你只需要运行:

      awk '{print $1","$2","$3","$4","$5}' /tmp/some.txt >> /tmp/some.csv
      

      【讨论】:

      • 没错,这是一个更好的答案。我只是使用了@Kart 写的相同命令。
      【解决方案4】:

      使用tr,挤压(-s),然后音译空格/制表符([:blank:]):

      tr -s '[:blank:]' ',' <file.txt
      

      使用sed,将一个或多个空格/制表符替换为,

      sed 's/[[:blank:]]\+/,/g' file.txt
      

      使用awk,使用gsub() 函数将一个或多个空格/制表符替换为,

      awk 'gsub("[[:blank:]]+", ",", $0)' file.txt
      

      示例

      % cat foo.txt
      JOHN              YES     6          6            2345762
      SHAUN             NO     6          6            2345748
      
      
      % tr -s '[:blank:]' ',' <foo.txt                     
      JOHN,YES,6,6,2345762
      SHAUN,NO,6,6,2345748
      
      % sed 's/[[:blank:]]\+/,/g' foo.txt                   
      JOHN,YES,6,6,2345762
      SHAUN,NO,6,6,2345748
      
      % awk 'gsub("[[:blank:]]+", ",", $0)' foo.txt
      JOHN,YES,6,6,2345762
      SHAUN,NO,6,6,2345748
      

      【讨论】:

      • 不错!我不知道你可以用tr 一次性挤压和替换。