regex - Bash 脚本 - 用于转储文件列表的正则表达式

标签 regex linux bash find

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

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

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

################################################################################
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

所以我的 2 个问题与同一段代码相关:

  1. REGEX:什么是正确的正则表达式,能够按扩展系列解析和转储文件(请参阅 4 SEARCH 模式和相关转储)?

  2. ARRAYS:解决了上述问题后,如何将包含 $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]}
    

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

谢谢

最佳答案

将代码中的 REGEX 行更改为:

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

用于匹配文件基本名称的 perl 正则表达式在单引号中。这可以防止 shell 尝试扩展它。 $ext 在双引号中,所以它会被 shell 扩展。尾随的 $ 用反斜杠转义只是为了形式。

前导 ^(.*/|) 将匹配前导目录(以/结尾),[^/\.]+ 将匹配一个或多个不是“.”的字符。或者 '/'。之后必须跟一个“.”。和您的扩展名,后跟要匹配的文件名结尾 ($)。

此处的关键是在两端(^ 和 $)锚定您的匹配并且不允许任何点“.”。除了你真正想要的。

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

关于regex - Bash 脚本 - 用于转储文件列表的正则表达式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53642786/

相关文章:

ruby - 转换 HTML 文档中的 URL?

c - 用 gdb 调试 c 程序以显示十六进制地址

python - 脚本执行时间[编辑]

linux - Bash 脚本,以确保只有一个脚本实例正在运行而其他脚本正在等待

linux - 设备树中根节点的模型字段

bash - 如何在 bash if 语句中使用 bc?

python - 单个正则表达式的多组匹配

Java Regex : Replacing full stops with spaces, 或删除它们(如果它们是缩写的一部分)

java - 在 JAVA 中验证 CSV 的正则表达式

linux - 如何使用 curl.h 在我的网络服务器上安装 git 没有这样的文件错误