大文件数据处理求助:如何保留第2列起的0、1、-1、2并过滤无效值?
解决方案:用awk高效处理列筛选需求
我来帮你搞定这个问题!针对你处理大文件的需求,awk是最适合的工具——它天生擅长按列处理文本,而且效率极高,完全能应付几千行/列的大文件。
具体命令
直接运行这条命令就能实现你的需求:
awk '{printf "%s", $1; for (i=2; i<=NF; i++) if ($i ~ /^-?[012]$/) printf " %s", $i; print ""}' input.txt > output.txt
命令解释
让我拆解一下每部分的作用:
printf "%s", $1:先保留并打印第一列(因为你不需要修改第一列的内容)for (i=2; i<=NF; i++):从第2列开始,遍历当前行的每一列(NF是awk内置变量,表示当前行的列数)if ($i ~ /^-?[012]$/):核心判断逻辑——用正则表达式匹配符合要求的数值:^和$确保完全匹配(避免像-12或10这类包含目标数字但不符合的内容)-?表示可选的负号(匹配-1)[012]只允许0、1、2这三个数字
printf " %s", $i:如果当前列符合要求,就打印它(前面加空格保证格式正确)print "":每一行处理完成后换行,保证输出格式和原文件一致
测试验证
用你提供的输入示例测试这条命令:
输入示例:1 55 -1 6|6 0 0 -1 1 2 0 1 56 -1 0 1 0 1 -1 -1 2 0 1 63 3|3 -1 0 0 1 -1 -1 2 1 73 -1 2 0 1 -1 -1 -1 0 1 75 -1 0 0 0 7|7 -1 -1 4|4 -1 1 80 -1 0 0 0 -1 5|5 -1 0 0 1 83 -1 1 1 0 -1 -1 -1 -1
处理后会得到你期望的输出:
1 56 -1 0 1 0 1 -1 -1 2 0 1 73 -1 2 0 1 -1 -1 -1 0 1 83 -1 1 1 0 -1 -1 -1 -1
额外提示
如果需要原地修改原文件,可以搭配sponge工具(很多Linux发行版默认自带,没有的话用包管理器安装):
awk '{printf "%s", $1; for (i=2; i<=NF; i++) if ($i ~ /^-?[012]$/) printf " %s", $i; print ""}' input.txt | sponge input.txt
⚠️ 注意:原地修改前最好先备份原文件,避免意外数据丢失。
内容的提问来源于stack exchange,提问作者Waqas Khokhar
相关产品推荐
相关产品推荐

