使用 echo 提取文件名的最后部分 - 使用通配符分配变量

使用 echo 提取文件名的最后部分 - 使用通配符分配变量

我正在尝试提取文件名的部分内容,我想提取第一个 _ 之后的所有内容,并且我找到了一个可行的解决方案,请参见下文

file=22NGS71294_S191_R1_001.fastq.gz
echo $file
22NGS71294_S191_R1_001.fastq.gz
echo ${file#*[_ ]}
S191_R1_001.fastq.gz

但是,当我使用通配符时,它停止工作

file2=*R1*
echo $file2
22NGS71294_S191_R1_001.fastq.gz
echo ${file2#*[_ ]}
22NGS71294_S191_R1_001.fastq.gz

我不知道为什么这不起作用,因为 $file 和 $file2 的 echo 命令给出了完全相同的结果。有人可以解释一下这种行为吗?

答案1

如果您使用sh, ksh, bash(或zsh 没有设置了该globassign选项),那么文件名生成(又名“globbing”)不会发生在标量赋值的 RHS 上,例如file2=*R1*

您的echo $file2回报是22NGS71294_S191_R1_001.fastq.gz因为未引用的扩展$file2受此时文件名生成的影响,但echo ${file2#*[_ ]}实际上相当于echo ${'*R1*'#*[_ ]}echo *R1*.参见示例什么时候需要双引号?

在 ksh/bash/zsh 中你可以使用大批分配 - 无论如何你可能应该这样做,因为通常*R1*可能会生成多个文件名。例如在 bash 中:

shopt -s nullglob

file2=(*R1*)
echo "${file2[@]#*_}"

相关内容