Quiero excluir cualquier archivo que termine con '.ses' o archivos sin extensión usando el siguiente patrón de expresiones regulares. Funciona bien en la línea de comandos pero no en un shell (bash/ksh).
Patrón de expresión regular: "\.(?!ses\$)([^.]+\$)"
Ejemplos de nombres de archivo:
"/test/path/test file with spaces.__1" (expected true) "/test/path/test file with spaces.ses" (expected false) "/test/path/test file with spaces" (expected false) "/test/path/test file with spaces.txt" (expected true) FILE_NAME="/test/path/test file with spaces.__1" PATTERN_STR="\.(?!ses\$)([^.]+\$)" if [[ "${FILE_NAME}" =~ ${PATTERN_STR} ]]; then Match_Result="true" else Match_Result="false" fi echo $Match_Resultdevuelve "verdadero" pero "falso" en el shell. ¿Alguien sabe por qué?
Simplemente usaría una declaración de caso con globos adecuados:
case "${FILE_NAME##*/}" in *.ses) Match_Result=false ;; *.*) Match_Result=true ;; *) Match_Result=false ;; esacConsidere usar una matriz en lugar de hacer gimnasia de espacios en blanco.
Puede invertir su lógica y fallar todas las cadenas que contienen .ses al final o que no contienen un punto después del último / .
Entonces, puedes usar este script :
#!/bin/bash declare -a arr=("/test/path/test file with spaces.__1" "/test/path/test file with spaces.ses" "/test/path/test file with spaces" "/test/path/test file with spaces.txt") # true false false true PATTERN_STR='(/[^/.]+|\.ses)$' for FILE_NAME in "${arr[@]}"; do if [[ "$FILE_NAME" =~ $PATTERN_STR ]]; then Match_Result="false" else Match_Result="true" fi echo $Match_Result done;Producción:
true false false trueDetalles :
( - inicio de un grupo de captura:/[^/.]+ - / y luego uno o más caracteres distintos de / y .| - o\.ses - .ses) - fin de la agrupación$ - final de una cadena. Se habilita una versión que no distingue entre mayúsculas y minúsculas con shopt -s nocasematch / shopt -u nocasematch (consulte Regex que no distingue entre mayúsculas y minúsculas en Bash ).