用于从文本生成csv文件的Bash脚本
我有一个包含记录的文本文件:用于从文本生成csv文件的Bash脚本,bash,shell,sh,export-to-csv,Bash,Shell,Sh,Export To Csv,我有一个包含记录的文本文件: Data1 Data2 ... Data50 我必须以以下格式从上述文本文件创建.csv文件: Type | Count | Name Def | u1 | Data1 Def | u2 | Data2 .... | ..... | .... Def | u50 | Data50 我需要一个bash脚本来从文本文件生成.csv文件。我不熟悉shell脚本!我也学习了awk和sed的基
Data1
Data2
...
Data50
我必须以以下格式从上述文本文件创建.csv文件:
Type | Count | Name
Def | u1 | Data1
Def | u2 | Data2
.... | ..... | ....
Def | u50 | Data50
我需要一个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
#/bin/bash
type=“Def”
x=1
count=“u”
对于../test.txt中的F
做
{
读取\n
echo“$type,$count$x,$…”>>../test.csv
x=x+1
}<$F
完成
我知道字段分隔符是“\n”。从那以后我有点迷路了
谢谢 第二个字段是:
x = `expr $x + 1`
$count$x
整个脚本变为:
#!/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
祝你好运 Your
for
循环将只循环一次,它循环您列出的令牌,而您只列出了一个(看起来像文件名,所以我猜您希望循环文件中的行):
在循环外部重定向更有效,因为shell不必关闭并重新打开输出文件
如果要在命令行上传入变量文件名,只需将硬编码的。/test.txt
替换为“$1”
。您可以类似地参数化输出文件名,但我只需删除输出重定向,并让调用方决定如何处理脚本的输出
如果需要读取多个字段并用逗号拆分,请调整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
建议优先于echo
,尤其是在您的输出要求不重要的情况下。我没有特别引用$I
,以消除nl
在行号之前添加的任何前导空格。否则,除非您特别指定,否则通常应在变量周围使用双引号要求shell对值执行空白标记化和通配符扩展。)如果已安装perl,则
perl -lnE 'say qq{Def,u$.,"$_"}' < inputfile
那么
seq -f 'Some Data%g' 50 | perl -lnE 'say qq{Def,u$.,"$_"}'
印刷品
Def,u1,"Some Data1"
Def,u2,"Some Data2"
...
Def,u49,"Some Data49"
Def,u50,"Some Data50"
我引用了最后一个字段,因为在输入中可以得到、
或空格
基于@Roland comment,添加标题行:
cat data | (echo 'Type,Count,Name' ; perl -lnE 'say qq{Def,u$.,"$_"}')
或
如果您想要bash
解决方案,只需使用:
cat -n filename | sed 's/ *\(.*\)\t\(.*\)/Def,u\1,"\2"/'
还是拯救世界
cat -n - | sed 's/ *\(.*\)\t\(.*\)/Def,u\1,"\2"/'
输入一些文件,如“makecsv”,并将其用作
./makecsv < data
/makecsv<数据
Ps:hmm.@tripleee的
nl
短为cat-n
;)将其保存在一个文件中,例如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
然后运行为:
cat ../test.txt | ./makecsv.rc > ../test.csv
如果需要,您可以执行chmod+x makecsv.rc
优点是输入/输出文件名不是硬编码的!谢谢我错过了。谢谢你!但是我被困在如何将“Data1,Data2…Data50”从.txt文件写入一个新的.csv文件中。我用Cygnus在我的台式电脑上测试了这一点,同时在笔记本电脑上执行stackoverflow,所以我不得不重新键入它。我打字出错了吗?你是对的。我使用带反引号的
cat
进行了更正。抱歉回答得太快:-)我尝试了你的代码,但for循环似乎不适用于catcommand@Pbmsread
可以读取多个变量,只需列出所需的字段即可<代码>读取时-r第一秒休息;做不要忘记csv标题行!这仍然很容易添加到您的解决方案中x=((x+1))
对我不起作用,太糟糕了,我不喜欢expr
@Roland使用x=$((x+1))
或让x++
非常感谢您花时间。你说得对,我想读一个文件中的多行。就像我提到的,我对bash脚本还不熟悉。所以我尝试了你提供的第一个代码,它给了我“done”的语法错误!你能给我一些关于外部实用程序的细节吗?有很好的理由省略标题行。因为OP的例子也没有,所以我没有添加一个;如果有标题行,建议不要使用。在此处添加csv标题行也很容易。对此很抱歉,但目前我正在处理大量csv文件,令人惊讶的是,标题行经常被无故省略。即使是包含24列的csv文件……如果不想硬编码文件名,也只需使用“$1”
和“$2”
。backticks中的cat
非常可怕。这非常有帮助,因为我需要使用不同的文件以一定的间隔执行它!非常感谢@你说得对。但在我的时区,肯定是该回家的时候了。请建议如何避免脚本和命令行中的两个cat
s:问题。我在自己的答案中添加了一个片段。你的可以进行类似的重构,但答案几乎相同…@Roland我的评论是针对其他用户的,他们可以使用该解决方案,他们可以拥有一个空间。记住,答案也是为未来的用户准备的。我不想批评你的答案,但老实说,我同意@tripleee——backtick中简单的cat
非常可怕,它反对任何良好的bash实践。此外,在任何现代shell中,$(命令)
作为backticks更为可取。
cat -n - | sed 's/ *\(.*\)\t\(.*\)/Def,u\1,"\2"/'
./makecsv < data
#!/bin/sh
echo Type,Count,Name
x=0
for f in `cat`
do
x=`expr $x + 1`
echo Def,u$x,$f
done
cat ../test.txt | ./makecsv.rc > ../test.csv