You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

使用Sed批量修改多TSV文件第二列内容并覆盖原文件

批量修改TSV文件第二列并保存回原文件的解决方案

我懂你遇到的问题了——直接用重定向>保存修改内容时,shell会先清空原文件,导致awk根本读不到数据,自然没法完成修改。下面给你两种可靠的解决办法:

方法一:awk + 临时文件(通用且安全)

这是最稳妥的方案,用临时文件中转处理后的内容,再替换原文件:

# 遍历当前目录下所有.tsv文件
for file in *.tsv; do
  # 处理内容:表头直接输出,其他行给第二列加前缀
  awk 'NR==1{print; next} {$2="X1_"$2; print}' "$file" > "$file.tmp"
  # 用临时文件覆盖原文件
  mv "$file.tmp" "$file"
done

代码解释:

  • NR==1{print; next}:识别第一行(表头),直接打印后跳过后续逻辑,保证表头不变
  • {$2="X1_"$2; print}:从第二行开始,给第二列拼接X1_前缀,然后输出整行
  • 先输出到临时文件再替换,避免了直接重定向清空原文件的坑

如果你的TSV是严格用制表符分隔的(不是空格),可以指定分隔符来保证格式不混乱:

for file in *.tsv; do
  awk -F '\t' -v OFS='\t' 'NR==1{print; next} {$2="X1_"$2; print}' "$file" > "$file.tmp"
  mv "$file.tmp" "$file"
done

这里-F '\t'指定输入分隔符为制表符,OFS='\t'指定输出分隔符为制表符,确保处理后还是标准TSV格式。

方法二:用sponge工具(更简洁)

如果你的系统安装了moreutils工具包(Ubuntu/Debian可以用sudo apt install moreutils安装),可以用sponge工具直接把处理结果写回原文件,省去临时文件的步骤:

for file in *.tsv; do
  awk 'NR==1{print; next} {$2="X1_"$2; print}' "$file" | sponge "$file"
done

sponge的作用是先把所有输入内容读入内存,再写入目标文件,不会提前清空原文件,完美解决了直接重定向的问题。

重要提醒

操作前一定要备份文件! 比如先把所有TSV文件复制到备份目录:

mkdir -p tsv_backup
cp *.tsv tsv_backup/

避免误操作导致数据丢失,毕竟数据安全永远是第一位的~

内容的提问来源于stack exchange,提问作者Natha

火山引擎 最新活动