如何在Bash中检查文本指定列内容并清空缺失列的注释
处理注释文件的Bash解决方案
我来帮你解决这个问题!针对你的需求,我们可以用两种方式实现:一种是你考虑的while循环逐行处理,另一种是用awk(更适合文本处理场景,代码更简洁高效)。
方法一:Bash while循环实现
这个方法会逐行读取文件,准确提取每一列(包括带空格的arabi-defline列),然后判断第三、第四列是否为空,再决定输出内容:
#!/bin/bash # 输入输出文件名,你可以根据实际修改 input_file="input.txt" output_file="output.txt" # 读取并输出表头 read -r header < "$input_file" echo "$header" > "$output_file" # 逐行处理数据行 tail -n +2 "$input_file" | while IFS= read -r line; do # 提取前三个字段 pac_id=$(echo "$line" | awk '{print $1}') locus_name=$(echo "$line" | awk '{print $2}') best_hit=$(echo "$line" | awk '{print $3}') # 提取arabi-defline列(第三字段之后的所有内容,去掉开头空格) arabi_defline=$(echo "$line" | awk '{$1=$2=$3=""; print substr($0, 4)}') # 检查Best-hit-arabi-name和arabi-defline是否都为空 if [[ -z "$best_hit" && -z "$arabi_defline" ]]; then # 清空注释内容,输出前两列加两个空列 echo "$pac_id $locus_name " >> "$output_file" else # 正常输出原行 echo "$line" >> "$output_file" fi done
代码说明:
tail -n +2:跳过表头,只处理数据行awk '{print $1}':提取第一列,同理$2、$3提取第二、第三列awk '{$1=$2=$3=""; print substr($0, 4)}':清空前三个字段后,从第4个字符开始输出,得到完整的arabi-defline内容(包括空格)[[ -z "$var" ]]:判断变量是否为空字符串
方法二:用awk直接处理(推荐)
awk天生适合处理结构化文本,代码更简洁,执行效率也更高:
BEGIN { # 设置输出字段分隔符为空格,和原文件保持一致 OFS=" " } # 表头直接输出 NR == 1 { print next } # 判断第三列和arabi-defline是否都为空 $3 == "" && length($0) <= length($1) + length($2) + 2 { # 输出前两列加两个空列,清空注释内容 print $1, $2, "", "" } # 其他情况正常输出原行 { print }
你可以把这段代码保存为process_comments.awk,然后用以下命令执行:
awk -f process_comments.awk input.txt > output.txt
代码说明:
NR == 1:处理第一行(表头),直接输出$3 == "" && length($0) <= length($1) + length($2) + 2:判断第三列是空,且整行长度不超过前两列长度加两个空格(说明后面没有有效内容)print $1, $2, "", "":输出前两列,后两列留空,实现清空注释的效果
内容的提问来源于stack exchange,提问作者Salomé Friry
相关产品推荐
相关产品推荐

