Bash批量处理多CSV文件 替换单列模式提取目标字段方法
问题原因
你写的命令无法得到预期结果,核心问题有3个:
- sed表达式用单引号包裹时,shell不会解析引号内的
${line}变量,变量不会被替换为实际值 - sed的正则语法里
*代表前一个字符匹配0次或多次,不是shell通配符里的任意字符语义,匹配规则写的不对 - 逻辑上没有逐行提取样本号,也没有指定输入源给sed,sed会一直等待标准输入,不会自动处理文件内容
正确实现方案
最简洁高效的方式是用awk直接批量处理所有csv文件,不需要写shell循环:
# 执行后结果直接打印在终端,需要保存到文件就在命令末尾加 > 合并后结果.csv awk ' BEGIN {FS=OFS=","} /^#sample/ {print; next} { split($1, sample_part, "-") $1 = sample_part[3] print } ' *.csv
命令逻辑说明:
BEGIN {FS=OFS=","}设定输入、输出的字段分隔符都为逗号,适配csv格式- 匹配到以
#sample开头的表头行时直接原样输出,跳过后续处理 - 对所有非表头行,将第一个字段(原SPH开头的长样本名)用
-分割,取第三段也就是HG开头的样本编号替换原第一个字段,再打印整行 - 直接通过
*.csv通配符传入所有待处理文件,awk会自动逐个读取处理,避免循环遍历的冗余写法
如果习惯用sed实现,也可以用下面的循环写法:
# 先提取第一个文件的表头写入结果文件 head -n 1 *.csv | head -n1 > 合并后结果.csv # 遍历所有csv文件 for f in *.csv; do # 跳过每个文件的表头行,通过正则捕获提取HG开头的样本号替换原长样本名,结果追加到结果文件 sed -n '1!s/^[^-]*-[^-]*-\([^-]*\)-[^,]*,/\1,/p' "$f" >> 合并后结果.csv done
内容的提问来源于stack exchange,提问作者Chen
相关产品推荐
相关产品推荐

