使用Bash提取制表符分隔文件第四列为12的行输出为空如何解决
问题原因分析与解决建议
错误原因
- 输出目录不存在:你脚本中使用的输出路径为
/home/user/extra/$file/(也就是/home/user/extra/random/),如果没有提前创建该目录,shell重定向操作会直接失败,最终生成的文件就是空文件。 - 字段格式不匹配:从你给出的文件样例可以看到,部分行的第四列末尾带了英文句号(比如样例中的
12.),这种情况下$4 == 12的判断会失败:awk读取到的$4是字符串"12.",和数字12做相等判断时结果为假,所以不会匹配到对应的行。 - 分隔符实际不匹配:你指定了
-F"\t"作为分隔符,如果你的文件实际是用多个空格、而非制表符分隔列,awk会把整行识别为一个字段,$4不存在,自然没有匹配结果。
解决建议
- 提前创建输出目录:在脚本开头加上
mkdir -p /home/user/extra/$file/,-p参数会自动创建层级父目录,目录已存在时也不会报错。 - 修改字段比较逻辑:强制把第四列转为数值类型后再做比较,自动忽略末尾的句号,
"12." + 0的数值计算结果就是12,可以匹配需求。 - 兼容多空白分隔符:如果不能确定文件是制表符还是空格分隔,可以把分隔符改成
-F"[[:space:]]+",支持任意数量的空白字符作为分隔符。
修改后可用脚本
file='random' # 提前创建输出目录 mkdir -p /home/user/extra/$file/ FILES=/home/user/data/*.txt for f in $FILES; do echo $f filename=$(basename $f) # 兼容带句号的字段、任意空白分隔符的逻辑 awk -F"[[:space:]]+" '{val = $4 + 0} val == 12' "$f" > "/home/user/extra/$file/$filename" done
内容的提问来源于stack exchange,提问作者John
相关产品推荐
相关产品推荐

