Bash字面匹配

时间:2016-08-10 13:03:20

标签: bash shell pattern-matching

我的剧本

#!/bin/bash

shopt -s extglob
for i in *.dat;
do
    if [[ "$i" == *(_TEx) ]];then
        file1=$i
    fi
done

echo file1="$file1"

我已经测试了脚本 http://www.shellcheck.net/

$ shellcheck myscript
No issues detected!

文件

262_V01_C00_R000_TEx_BL_2048H.dat
262_V01_C01_R000_TEy_BL_2048H.dat
262_V01_C02_R000_THx_BL_2048H.dat
262_V01_C03_R000_THy_BL_2048H.dat

但是

milenko@milenko-HP-Compaq-6830s:~/procmt$ bash a8.sh 
file1=

为什么?

3 个答案:

答案 0 :(得分:4)

对您尝试使其工作的最小修改将是:

    if [[ "$i" == *_TEx* ]]; then

即。删除括号并在模式的末尾添加缺少的*。无需设置extglob shell选项,因为您不需要使用其任何功能。

但是,你也可以将你正在循环的glob更改为:

for i in *_TEx*.dat;

并完全避免使用if

更好的是,你可以直接打印比赛:

shopt -s nullglob
printf '%s\n' *_TEx*.dat # print all files matching the pattern

nullglob在这里非常有用,因为当没有文件与模式匹配时,它将导致无输出。

答案 1 :(得分:3)

pyinstaller --onefile --clean pythonfile.py 匹配的文件名只包含反复重复的字符串 %macro combine; data modelfit; set %do i = 30 %to 116 %by 3 ; stat&i %end; ; %end; run; %mend; %combine; ,如*(_TEx)中所示。

您要找的是_TEx,不需要扩展的glob。然后你可以将它与_TEx_TEx_TEx_TEx glob结合起来并完全摆脱循环。

*_TEx*

答案 2 :(得分:2)

Tom Fenech's helpful answerJohn Kugelman's helpful answer向您展示基于简单全球的有效解决方案。

如果你想尝试使用扩展通配符,那么你已经尝试了(样本输入):

[[ "$i" == *@(_TEx)* ]]

或者,将这个glob折叠成循环glob:

for i in *@(_TEx)*.dat; do # ...

假设shopt -s extglob,但请注意在[[ ... ]]内,在Bash v4.1 +中为{{1}的RHS隐式启用扩展的globbing }和==

  • 简单和扩展的glob都与整个文件名匹配,因此!=本身是不够的 - 您必须提供封闭的*(_TEx)个字符。以便匹配模式之前和之后的字符。

  • Extended-glob构造*匹配零或更多*(_TEx)次出现,有效匹配:(a)空字符串,或(b)任何_TEx的重复次数;与封闭的_TEx字符结合使用,可有效匹配所有文件名;
    相比之下,*匹配恰好一个出现@(_TEx)(但是,如引用的答案中所示,在简单的glob中简单地包含_TEx也是如此。 )。