如何用awk按首列首字符为A且长度为6拆分TXT文件
原有命令失效的核心原因
你尝试运行的命令awk -F '|' '$1 == "A*****" {print > ("BeginsWithA.txt"); next} {print > ("Rest.txt")}' FileToSplit.txt没有输出符合预期的结果,问题主要有两个:
- awk中使用
==做匹配时是精确字符串比对,"A*****"代表字面意义的「字符A加5个连续星号」,并不是你想要的“开头为A、后续任意5个字符”的通配规则 - 完全缺失首列字段的长度判断逻辑,和你设定的拆分规则不匹配
可直接运行的拆分命令
按照你给出的「首列首字符为A、且首列总字符长度为6」的规则,直接运行以下命令即可生成对应拆分文件:awk -F '|' 'substr($1,1,1)=="A" && length($1)==6 {print > "BeginsWith6.txt"; next} {print > "Rest.txt"}' FileToSplit.txt
注:如果需要调整匹配结果的输出文件名,直接替换引号内的文件名即可,比如改回BeginsWithA.txt
命令逻辑逐段拆解
-F '|':指定竖线|为列分隔符,和你原文件的字段格式匹配substr($1,1,1)=="A":提取第一列从第1个字符开始、长度为1的子串,判断是否等于字符"A",对应“首列首字符为A”的要求length($1)==6:调用awk内置的length()函数直接获取第一列的总字符数,判断是否等于6,补上你之前缺失的长度判断逻辑- 同时满足两个条件的行:直接写入
BeginsWith6.txt,触发next命令跳过后续逻辑,避免被重复写入另一个文件 - 所有不满足条件的行:统一写入
Rest.txt
样例匹配验证
按你提供的输入文件内容运行后,两个输出文件的内容和你给出的预期完全一致:
BeginsWith6.txt 存储符合规则的行:
A35646|Line 3|Stuff 3
A48029|Line 5|Stuff 5
A32100|Line 6|Stuff 6Rest.txt 存储所有剩余行:
2134|Line 1|Stuff 1
31516784|Line 2|Stuff 2
641|Line 4|Stuff 4
413|Line 7|Stuff 7
可选场景优化
如果你的首列字段可能存在首尾空格,会导致长度计算出现偏差,可以在判断逻辑前增加一段去除首尾空格的处理:awk -F '|' '{gsub(/^[[:space:]]+|[[:space:]]+$/,"",$1)} substr($1,1,1)=="A" && length($1)==6 {print > "BeginsWith6.txt"; next} {print > "Rest.txt"}' FileToSplit.txt
内容的提问来源于stack exchange,提问作者CLSA

