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
Bash Script to generate csv file from text
提问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 for
loop 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.txt
with "$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
(printf
is recommended over echo
, especially if your output requirements are nontrivial. I fail to quote $i
specifically to get rid of any leading whitespace added by nl
before 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' 50
will 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 bash
solution, 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 nl
is 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!
祝你好运!