代码之家  ›  专栏  ›  技术社区  ›  hornetbzz atiruz

bash脚本-regex转储文件列表

  •  0
  • hornetbzz atiruz  · 技术社区  · 6 年前

    由于以前的工作,我有4个文件扩展名,存储在$search数组中,如下所示:

    declare -a SEARCH=("toggled" "jtr" "jtr.toggled" "cupp")
    

    我想为上述4种扩展模式中的每一种发布一个文件列表,如下所示,但带有2个点和2个扩展名(标记为“否”)的情况除外:

    ################################################################################
    1 - SEARCH FOR toggled in /media
    regex   : ([^\/]+)(\.)(toggled)$
    command : find /media -type f | grep --color -P ([^\/]+)(\.)(toggled)$
    ################################################################################
    /media/myfile_1.jtr.toggled --> NO
    /media/myfile_1.toggled
    /media/myfile_2.jtr.toggled --> NO
    /media/myfile_2.toggled
    /media/myfile_3.jtr.toggled --> NO
    /media/myfile_3.toggled
    
    
    ################################################################################
    2 - SEARCH FOR jtr in /media
    regex   : ([^\/]+)(\.)(jtr)$
    command : find /media -type f | grep --color -P ([^\/]+)(\.)(jtr)$
    ################################################################################
    /media/myfile_1.jtr
    /media/myfile_2.jtr
    /media/myfile_3.jtr
    
    
    ################################################################################
    3 - SEARCH FOR jtr.toggled in /media
    regex   : ([^\/]+)(\.)(jtr.toggled)$
    command : find /media -type f | grep --color -P ([^\/]+)(\.)(jtr.toggled)$
    ################################################################################
    /media/myfile_1.jtr.toggled
    /media/myfile_2.jtr.toggled
    /media/myfile_3.jtr.toggled
    
    
    ################################################################################
    4 - SEARCH FOR cupp in /media
    regex   : ([^\/]+)(\.)(cupp)$
    command : find /media -type f | grep --color -P ([^\/]+)(\.)(cupp)$
    ################################################################################
    /media/myfile_1.cupp
    /media/myfile_2.cupp
    /media/myfile_3.cupp
    

    显然我花了好几个小时 regex101 W/O成功。 我还尝试使用其他方法来实现我的目标,这些方法不适合代码的其余部分。

    以下是代码摘录:

    for ext in "${SEARCH[@]}"
    do
    
        COUNTi=$((COUNTi+1))
    
        REGEX="([^\/]+)(\.)("$ext")$" #
        # Ideally, the Regex should come from a pattern array
    
        printf '%*s' "$len" | tr ' ' "$mychar"
        echo -e "\n$COUNTi - SEARCH FOR $ext in $BASEDIR"
        echo "regex   : $REGEX"
        echo "command : find $BASEDIR -type f | grep --color -P $REGEX"
        printf '%*s' "$len" | tr ' ' "$mychar" && echo
    
        find $BASEDIR -type f | grep --color -P $REGEX 
        # the Regex caveats as the double dot extensions are not parsed correctly.
    
        echo -e "\n"
    
    done
    

    所以我的两个问题与同一段代码有关:

    1. regex:什么是正确的regex,能够按扩展家族解析和转储文件(请参见4个搜索模式和相关转储)?

    2. 数组:一旦解决了上述问题,如何将包含$extension占位符的模式数组数据使用到循环regex中?

       PATTERN+=( "([^\/]+)(\.)($ext)$" )
      # All of these below : CAVEATS escaping $ or not...
      # REGEX=${PATTERN[5]}
      # REGEX=$(eval "${PATTERN[5]}" )
      # echo "pattern : ${PATTERN[5]}"
      # eval "$REGEX=\$REGEX"
      # eval "$REGEX=\"\$REGEX\""
      # REGEX=$(echo "${REGEX}")
      # REGEX=${!PATTERN[5]}
      

    笔记: 我花了几个小时阅读了所有的regex文档,尝试了数百种regex模式,但没有成功,因为我不理解这些regex的基本原理。
    我也尝试过其他方法,例如 find / -name "sayONEnameinmysearchpattern" ! -iname "theothernamesfromtehsearchpattern" . 这不是我要找的。

    谢谢

    1 回复  |  直到 6 年前
        1
  •  2
  •   Robert Birdsall    6 年前

    将代码中的regex行更改为:

    REGEX='^(.*\/|)[^\/\.]+\.'"$ext\$"
    

    与文件的基名称匹配的Perl正则表达式使用单引号。这会阻止shell尝试展开它。$ext是双引号的,因此它将由shell扩展。尾随的$以反斜杠形式转义。

    前导^(./)将匹配前导目录(以/结尾),[^/\.]+将匹配一个或多个不是“.”或“/”的字符。然后必须在其后面跟一个“.”和扩展名,再跟文件名($)的结尾以匹配。

    这里的关键是在两端(^和$)定位匹配项,除了您真正想要的点外,不允许有任何点“.”。

    您可能还想将$regex放在引号中…”在grep命令中靠近代码提取末尾的$regex。

    推荐文章