Shell脚本中grep匹配变量无结果的问题排查求助
Shell脚本grep匹配失效:Windows换行符导致的问题
问题本质
你的strains_list_test文件采用了Windows格式的换行符(\r\n),而非Unix系统标准的换行符(\n)。当read命令读取每行内容时,会将行尾的\r(回车符)一并存入变量strain_name中,导致实际执行的grep命令是匹配类似p1.A2\r的字符串——但你的filtered2_sample.tsv是Unix格式,行尾没有\r,自然匹配不到结果。而直接使用固定字符串p8.H2时,没有多余的\r,所以能正常生效。
解决方案
1. 转换文件为Unix格式(推荐)
直接修改源文件的换行符格式,一劳永逸:
- 用
dos2unix工具(多数Linux发行版自带):dos2unix strains_list_test - 若无
dos2unix,用sed删除行尾的\r:sed -i 's/\r$//' strains_list_test
2. 在脚本内处理变量
如果不想修改源文件,可在读取行时自动去除\r:
- 方法一:用参数扩展删除变量末尾的
\r#!/bin/bash CURRENT_DIR=$(pwd) STRAINS="$CURRENT_DIR/strains_list_test" OUTPUT_DIR="$CURRENT_DIR/output" BLAST_FILE="$CURRENT_DIR/filtered2_sample.tsv" while read -r strain_name do # 去除变量末尾的\r strain_name=${strain_name%$'\r'} echo "strain name is $strain_name" grep "$strain_name" "$BLAST_FILE" | head done < "$STRAINS" echo "testing non-variable grep" grep "p8.H2" "$BLAST_FILE" | head - 方法二:用
tr先过滤整个文件的\r#!/bin/bash CURRENT_DIR=$(pwd) STRAINS="$CURRENT_DIR/strains_list_test" OUTPUT_DIR="$CURRENT_DIR/output" BLAST_FILE="$CURRENT_DIR/filtered2_sample.tsv" cat "$STRAINS" | tr -d '\r' | while read -r strain_name do echo "strain name is $strain_name" grep "$strain_name" "$BLAST_FILE" | head done echo "testing non-variable grep" grep "p8.H2" "$BLAST_FILE" | head
验证方法
你可以用cat -A命令查看文件的换行符细节:
cat -A strains_list_test
- Windows格式的行末尾会显示
^M$(^M是\r的可视化表示) - Unix格式的行末尾只会显示
$
内容的提问来源于stack exchange,提问作者Hek
相关产品推荐
相关产品推荐

