Bash Scripting-REGEX,用于转储文件列表



由于以前的工作,我有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上,但没有成功。我还尝试使用其他方法来实现我的目标,这些方法与代码的其余部分不匹配。

以下是代码摘录:

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:什么是正确的正则表达式,能够按扩展族解析和转储文件(请参阅4个搜索模式和相关转储(?

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

    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]}
    

注意:我阅读了几个小时的所有正则表达式文档,尝试了数百种正则表达式模式,但没有成功,因为我无法理解这些正则表达式的原理
我还尝试了其他方法,例如find / -name "sayONEnameinmysearchpattern" ! -iname "theothernamesfromtehsearchpattern"。这不是我想要的。

Thx

将代码中的REGEX行更改为:

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

与文件的基本名称匹配的perl正则表达式用单引号括起来。这样可以防止shell试图展开它。$ext用双引号括起来,因此它将由shell展开。尾部$用反斜杠转义,仅用于形式。

前导^(.*/|(将与前导目录(以/结尾(匹配,[^/\.]+将与一个或多个非"."字符匹配或"/"。然后必须跟一个"。"和您的扩展名,然后是要匹配的文件名末尾($(。

这里的关键是在两端(^和$(锚定你的比赛,不允许有任何点除了你真正想要的。

你可能还想把$REGEX放在引号里。。。在grep命令中靠近代码提取末尾的"$REGEX"。

最新更新