bash Bash脚本从文本生成csv文件

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/28700492/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-08 21:53:03  来源:igfitidea点击:

Bash Script to generate csv file from text

bashshellshexport-to-csv

提问by Tamaghna Guha Thakurta

I have a text file with records:

我有一个包含记录的文本文件:

  Data1

  Data2

  ...

  Data50

I have to create a .csv file from the above text file in the following format:

我必须按照以下格式从上述文本文件创建一个 .csv 文件:

Type |  Count | Name

Def |    u1 |    Data1

Def |    u2  |     Data2

....  |  .....   |  ....

Def  |   u50   | Data50

i need a bash script to generate the .csv file from the text file. I am new to shell scripting! I have gone through basics of awk and sed as well. I have a vague idea like:

我需要一个 bash 脚本来从文本文件生成 .csv 文件。我是 shell 脚本的新手!我也学习了 awk 和 sed 的基础知识。我有一个模糊的想法,例如:

#!/bin/bash
type="Def"
x=1
count="u"
for F in ../test.txt
do
    {
       read \n
       echo "$type, $count$x, $..." >> ../test.csv
       x=x+1
    } < $F

done 

I do understand that the field separator is '\n'. I am kind of lost after that.

我知道字段分隔符是 '\n'。在那之后我有点迷失了。

Thanks!

谢谢!

采纳答案by Roland

save this in a file, e.g. makecsv.rc:

将其保存在一个文件中,例如 makecsv.rc:

#!/bin/sh
echo Type,Count,Name
x=0
for f in `cat`
do
   x=`expr $x + 1`
   echo Def,u$x,$f
done

then run as:

然后运行为:

cat  ../test.txt | ./makecsv.rc > ../test.csv

if needed, you do chmod +x makecsv.rc

如果需要,你做 chmod +x makecsv.rc

The advantage is that the input/output file names are not hardcoded

优点是输入/输出文件名不是 hardcoded

回答by tripleee

Your forloop will only loop a single time, it loops over the tokens you list and you only listed one (which looks like a file name, so I'm guessing you want to loop over lines in the file):

您的for循环只会循环一次,它会遍历您列出的令牌,而您只列出了一个(看起来像一个文件名,所以我猜您想遍历文件中的行):

#!/bin/bash
type="Def"
x=1
count="u"
while read value; do
   echo "$type, $count$x, $value"
   let x++
done <../test.txt > ../test.csv

You could also use an external utility for the running numbers:

您还可以对运行数字使用外部实用程序:

nl ../test.txt |
while read -r x value; do
    echo "$type,$count$x,$value"
done >../test.csv

Redirecting outside the loop is more efficient because the shell won't have to close and reopen the output file.

在循环外重定向更有效,因为 shell 不必关闭并重新打开输出文件。

If you want to pass in a variable file name on the command line, just replace the hardcoded ../test.txtwith "$1". You could similarly parametrize the output file name, but I would simply remove the output redirection, and leave it to the caller to decide what to do with the script's output.

如果你想在命令行上一个变量文件名通过,只需更换硬编码../test.txt"$1"。您可以类似地参数化输出文件名,但我会简单地删除输出重定向,并将其留给调用者来决定如何处理脚本的输出。

If you need to read multiple fields and split on comma, tweak your IFS.

如果您需要读取多个字段并以逗号分隔,请调整您的IFS.

nl -s , ../test.txt |
while IFS=, read -r i first second rest; do
    printf "%i,%s,u%i,%s\n" $i "$first" "$second" "$rest"
done

(printfis recommended over echo, especially if your output requirements are nontrivial. I fail to quote $ispecifically to get rid of any leading whitespace added by nlbefore the line number. Otherwise, you should generally always use double quotes around your variables unless you specifically require the shell to perform whitespace tokenization and wildcard expansion on the value.)

(printf建议超过echo,特别是如果您的输出要求非常重要。我没有$i特别引用以去除nl行号之前添加的任何前导空格。否则,除非您特别需要 shell,否则通常应始终在变量周围使用双引号对值执行空白标记化和通配符扩展。)

回答by jm666

If you have perl installed, the

如果你安装了 perl,

perl -lnE 'say qq{Def,u$.,"$_"}' < inputfile

will do the job.

会做的工作。

demo:

演示:

the seq -f 'Some Data%g' 50will generate lines like:

seq -f 'Some Data%g' 50会产生这样的行:

Some Data1
Some Data2
...
Some Data50

so the

所以

seq -f 'Some Data%g' 50 | perl -lnE 'say qq{Def,u$.,"$_"}'

prints

印刷

Def,u1,"Some Data1"
Def,u2,"Some Data2"
...
Def,u49,"Some Data49"
Def,u50,"Some Data50"

I quoted the last field, because in the input you could get ,or spaces.

我引用了最后一个字段,因为在输入中你可以得到,或空格。

based on @Roland comment, adding a header line:

基于@Roland 评论,添加标题行:

cat data | (echo 'Type,Count,Name' ; perl -lnE 'say qq{Def,u$.,"$_"}')

or

或者

perl -lnE 'BEGIN{say q{Type,Count,Name}}say qq{Def,u$.,"$_"}'

If you want bashsolution, simply use:

如果你想要bash解决方案,只需使用:

cat -n filename | sed 's/ *\(.*\)\t\(.*\)/Def,u,""/'

or save the

或保存

cat -n - | sed 's/ *\(.*\)\t\(.*\)/Def,u,""/'

into some file, like "makecsv" and use it as

进入某个文件,如“makecsv”并将其用作

./makecsv < data

Ps: hmm.. the @tripleee's nlis shorter as cat -n;)

Ps: 嗯..@tripleee'snl更短cat -n;)

回答by Roland

You make the second field with:

您使用以下内容制作第二个字段:

x = `expr $x + 1`
$count$x

The entire script becomes:

整个脚本变成:

#!/bin/sh

echo Type,Count,Name > test.csv
x=0
for f in `cat test.txt`
do
   x=`expr $x + 1`
   echo Def,u$x,$f >> test.csv
done

Good Luck!

祝你好运!