You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用VIM/sed/awk将三列经纬坐标文本转为两列且不拆配对数据

坐标文本格式转换需求

我有一个大型文本文件,内容示例(简化版):

a1 b1 a2
b2 a3 b3
a4 b4 a5
b5 a6 b6 

实际存储的是配对的经度/纬度坐标,真实数据格式:

1.591336e+02 4.978998e+01 1.591162e+02
4.977995e+01 1.590988e+02 4.976991e+01
1.590815e+02 4.975988e+01 1.590641e+02
4.974984e+01 1.590468e+02 4.973980e+01

希望转换为不拆分配对数据的两列格式:

a1 b1 
a2 b2 
a3 b3
a4 b4 
a5 b5 
a6 b6 

我正在学习VIM,也能使用其他工具。试过用sed命令:

sed 's/\s/\n/2;P;D' file.txt > newfile.txt

转换后出现^M字符,用dos2unix去除后还是没得到目标格式。作为编程新手,怕误操作大文件,求指导!


解决方案

方法一:使用awk(推荐,逻辑清晰)

awk可以直接按字段处理,把每行的字段按顺序配对输出,同时自动处理换行符问题:

awk '{
    print $1, $2
    prev = $3
    getline
    print prev, $1
    print $2, $3
}' file.txt > newfile.txt

逻辑说明:

  • 读取第一行,输出前两个字段$1 $2
  • 把第一行第三个字段存到prev变量
  • 读取下一行,输出prev和当前行第一个字段$1
  • 输出当前行的$2 $3
  • 循环处理所有行,刚好匹配配对需求

如果要先处理DOS换行符(^M),可以先执行:

dos2unix file.txt

或者在awk里直接处理:

awk '{
    sub(/\r$/,"")  # 去掉行尾的^M
    print $1, $2
    prev = $3
    getline
    sub(/\r$/,"")
    print prev, $1
    print $2, $3
}' file.txt > newfile.txt

方法二:使用VIM(适合边看边改)

打开文件后,执行以下步骤:

  1. 先处理DOS换行符::set fileformat=unix 然后保存:w
  2. 执行全局替换命令,把两行内容重新组合:
:%s/\v^(\S+)\s+(\S+)\s+(\S+)\n(\S+)\s+(\S+)\s+(\S+)/\1 \2\r\3 \4\r\5 \6/g

逻辑说明:

  • \v开启非常魔法模式,简化正则写法
  • 匹配两行内容,捕获6个字段
  • 重新排列成三行配对的格式
  1. 如果文件行数是偶数,这个命令会批量处理所有行;如果是奇数,可以单独处理最后一行。

方法三:修正你的sed命令

调整sed命令逻辑,适配需求:

sed -e 's/\([^ ]* [^ ]*\) \([^ ]*\)/\1\n\2/' -e 'N;s/\n\([^ ]*\) \([^ ]*\) \([^ ]*\)/ \1\n\2 \3/' file.txt | dos2unix > newfile.txt

逻辑说明:

  • 第一部分:把每行拆成“前两个字段”+换行+“第三个字段”
  • 第二部分:把下一行读进来,把换行后的第三个字段和下一行第一个字段配对,再输出剩下的两个字段

注意事项
  • 处理大文件前,一定要先备份:cp file.txt file_backup.txt
  • 可以先拿小样本测试命令,确认结果正确后再处理大文件
  • 如果用VIM处理超大文件,建议加上:set noswapfile避免生成大交换文件

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.01 03:41:29