由于之前的工作,我有 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 个问题与同一段代码相关:
REGEX:什么是正确的正则表达式,能够按扩展系列解析和转储文件(请参阅 4 SEARCH 模式和相关转储)?
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"
.这不是我要找的。p>
谢谢
最佳答案
将代码中的 REGEX 行更改为:
REGEX='^(.*\/|)[^\/\.]+\.'"$ext\$"
用于匹配文件基本名称的 perl 正则表达式在单引号中。这可以防止 shell 尝试扩展它。 $ext 在双引号中,所以它会被 shell 扩展。尾随的 $ 用反斜杠转义只是为了形式。
前导 ^(.*/|) 将匹配前导目录(以/结尾),[^/\.]+ 将匹配一个或多个不是“.”的字符。或者 '/'。之后必须跟一个“.”。和您的扩展名,后跟要匹配的文件名结尾 ($)。
此处的关键是在两端(^ 和 $)锚定您的匹配并且不允许任何点“.”。除了你真正想要的。
您可能还想将 $REGEX 放在引号中...“$REGEX”在靠近代码提取末尾的 grep 命令中。
关于regex - Bash 脚本 - 用于转储文件列表的正则表达式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53642786/