使用bash/sed将文件名的一部分前置到.csv文件
我在一个目录中有几个文件,它们的名称如下使用bash/sed将文件名的一部分前置到.csv文件,bash,csv,sed,Bash,Csv,Sed,我在一个目录中有几个文件,它们的名称如下 1_38OE983729JKHKJV.csv 后跟ID的整数(整数和ID都是唯一的) 我需要为文件夹中的每个文件的每一行预先添加此ID,以准备导入数据库的文件(并放弃文件名的整数部分)。文件内容如下所示: BW;20015;11,45;0,49;41;174856;4103399 BA;25340;11,41;0,55;40;222161;4599779 BB;800;7,58;0,33;42;10559;239887 HE;6301;9,11;0,3
1_38OE983729JKHKJV.csv
后跟ID的整数(整数和ID都是唯一的)
我需要为文件夹中的每个文件的每一行预先添加此ID,以准备导入数据库的文件(并放弃文件名的整数部分)。文件内容如下所示:
BW;20015;11,45;0,49;41;174856;4103399
BA;25340;11,41;0,55;40;222161;4599779
BB;800;7,58;0,33;42;10559;239887
HE;6301;9,11;0,39;40;69191;1614302
.
.
.
Total;112613;9,33;0,43;40;1207387;25897426
38OE983729JKHKJV;BW;20015;11,45;0,49;41;174856;4103399
38OE983729JKHKJV;BA;25340;11,41;0,55;40;222161;4599779
38OE983729JKHKJV;BB;800;7,58;0,33;42;10559;239887
38OE983729JKHKJV;HE;6301;9,11;0,39;40;69191;1614302
.
.
.
38OE983729JKHKJV;Total;112613;9,33;0,43;40;1207387;25897426
最终结果应该如下所示:
BW;20015;11,45;0,49;41;174856;4103399
BA;25340;11,41;0,55;40;222161;4599779
BB;800;7,58;0,33;42;10559;239887
HE;6301;9,11;0,39;40;69191;1614302
.
.
.
Total;112613;9,33;0,43;40;1207387;25897426
38OE983729JKHKJV;BW;20015;11,45;0,49;41;174856;4103399
38OE983729JKHKJV;BA;25340;11,41;0,55;40;222161;4599779
38OE983729JKHKJV;BB;800;7,58;0,33;42;10559;239887
38OE983729JKHKJV;HE;6301;9,11;0,39;40;69191;1614302
.
.
.
38OE983729JKHKJV;Total;112613;9,33;0,43;40;1207387;25897426
谢谢你的帮助
编辑:拼写和发音为清晰起见使用在文件上循环,使用参数展开提取id
#!/bin/bash
for csv in *.csv ; do
prefix=${csv%_*}
id=${csv#*_}
id=${id%.csv}
sed -i~ "s/^/$id;/" "$csv"
done
如果ID可以包含下划线,则可能需要更加小心地进行扩展。使用awk工具:
for f in *csv; do awk '{ fn=FILENAME; $0=substr(fn,index(fn,"_")+1,length(fn)-6)";"$0 }1' "$f" > tmp && mv tmp "$f"; done
-文件名fn=FILENAME
awk 'FNR==1{close(val);val=FILENAME;split(FILENAME,a,"_");sub(/\..*/,"",a[2])} {print a[2]","$0}' *.csv
使用GNU awk进行就地编辑和gensub()只需:
awk -i inplace '{print gensub(/.*_(.*)\..*/,"\\1;",1,FILENAME) $0}' *.csv
没有shell循环或任何其他必要的东西,只有该命令。它给我这个错误:我的输入:sh addId.sh:command not found'ddId.sh:第3行:意外标记附近的语法错误
do'ddId.sh:line 3:
for csv in*.csv;doDon不要用sh
调用bash
脚本。我的错,谢谢!我习惯于使用macOS,sh实际上调用bash而不是标准的BourneShell。活到老学到老!我必须如何执行此操作?这必须在同一个目录中吗?@Tassanara:尝试在终端上运行,它只会打印行,如果您需要输出到单个输出文件,那么您可以在命令的最后执行>输出文件,然后告诉我它是如何运行的。@Tassanara:很高兴它帮助了您。这对多个文件不起作用。例如,close(val)
正试图关闭以前的FILENAME
值,但close()
仅适用于由于重定向而打开的文件(例如,print>file
或getline
),而不是作为常规工作循环的一部分。显然,打印到stdout一次只能处理1个文件,但不要尝试*.csv
。如果要对文件名使用split(),为什么不同时在\uu
和
处拆分它,而不是在\u
处拆分它,然后在
处拆分子()呢?split()的第三个参数是regexp,顺便说一句,不是字符串。最后,所需的分隔符是代码>,而不是,
;。