如何在Bash中使用变量切换cut命令的分隔符参数?
问题:cut命令通过变量传递分隔符参数失效的解决办法
问题背景
存在两类基因数据文件,一类为空格分隔,一类为制表符分隔,示例内容如下:
marker allele1 allele2 id1 id1 id2 id2 chr11_96001606 C T 1.25893e-12 1 3.16228e-26 0.000999001 chr1_46021459 G T 0.969347 0.0306534 1.22034e-21 0.996035
编写脚本判断文件分隔符并将参数存入FILESEP变量:
file=~/Desktop/test.geno.file.txt if cat $file | awk '{exit !/\t/}'; then echo "Tab delimited" # tab file FILESEP="" else FILESEP="-d \ " echo "Space delimited with $FILESEP" # space file fi onlyfile=$(basename $file)
需要用cut命令提取第一列并拆分染色体与位置,原有效命令为:
POSFILE=${onlyfile%.txt}.pos.gz # Next command will generate it cat $file | cut -d' ' -f 1 | perl -p -e 's/_([^_]+$)/\t$1/' | grep -v marker | gzip > ~/Desktop/$POSFILE # Keep position only chr \t pos
但将-d' '替换为$FILESEP后,命令无法正常运行。
问题原因
bash对变量进行词拆分时,会将-d \ 拆分为-d、\、 三个独立参数,导致cut无法识别错误的参数格式。
解决方案
方法1:用数组存储命令参数(推荐)
bash数组可正确保留参数结构,避免词拆分问题:
file=~/Desktop/test.geno.file.txt # 判断分隔符并设置cut参数数组 if awk '{exit !/\t/}' "$file"; then echo "Tab delimited" cut_args=(-f 1) # 制表符是cut默认分隔符,无需指定-d else echo "Space delimited" cut_args=(-d ' ' -f 1) fi onlyfile=$(basename "$file") # 执行处理命令 POSFILE=${onlyfile%.txt}.pos.gz cat "$file" | cut "${cut_args[@]}" | perl -p -e 's/_([^_]+$)/\t$1/' | grep -v marker | gzip > ~/Desktop/"$POSFILE"
方法2:改用awk完成全流程(更简洁健壮)
直接用awk自动检测分隔符、提取列并拆分染色体位置,无需依赖cut和参数传递:
file=~/Desktop/test.geno.file.txt onlyfile=$(basename "$file") POSFILE=${onlyfile%.txt}.pos.gz awk ' BEGIN { # 自动检测分隔符 if ((getline < ARGV[1]) > 0) { if (/\t/) FS="\t"; else FS=" "; close(ARGV[1]); } } NR>1 { # 跳过表头行 split($1, chr_pos, "_"); print chr_pos[1] "\t" chr_pos[2]; } ' "$file" | gzip > ~/Desktop/"$POSFILE"
方法3:修正变量赋值与引用(不推荐,存在安全风险)
若坚持用变量传递,可通过eval执行,但需注意变量的正确赋值:
file=~/Desktop/test.geno.file.txt if awk '{exit !/\t/}' "$file"; then echo "Tab delimited" FILESEP="" else FILESEP="-d ' '" echo "Space delimited" fi onlyfile=$(basename "$file") POSFILE=${onlyfile%.txt}.pos.gz cat "$file" | eval cut $FILESEP -f 1 | perl -p -e 's/_([^_]+$)/\t$1/' | grep -v marker | gzip > ~/Desktop/"$POSFILE"
内容的提问来源于stack exchange,提问作者M. Beausoleil
相关产品推荐
相关产品推荐

