ksh 中的正则表达式用于扩展 tgz、tar.tgz

ksh 中的正则表达式用于扩展 tgz、tar.tgz

我正在尝试获取正则表达式(在 ksh 中)来识别仅具有以下扩展名的文件:tgztar.gz和。我尝试了几个但无法让它们工作。我使用此正则表达式仅选择具有这些扩展名的文件来对它们进行一些处理:TGZTAR.GZ

if [ -f $myregexp ]; then
   ..... 
fi

答案1

[ -f "$myregexp" ][[ -f $myregexp ]]测试是否有一个名为$myregexp. (请注意,对于单括号,您需要双引号。)

如果您想测试是否存在与 glob 模式匹配的文件,则没有直接的方法。您必须分两步完成:首先生成匹配列表,然后测试该列表是否为空。

a=( ~(Ni)*.@(tgz|tar.gz) )
if [[ ${#a} -ne 0 ]]; then …

这使用了许多特定于 ksh 的功能:

  • ~(N)如果没有匹配则生成空列表的前缀;
  • ~(i)进行不区分大小写匹配的前缀;
  • @(foo|bar)要匹配的 glob语法foobar

这是 bash 的等价物。在 bash 中,您可以从选项中获得不匹配的全局变量和不区分大小写的大小写空扩展;extglob用于@(foo|bar)语法和其他 ksh glob 扩展。

shopt -s nocaseglob nullglob extglob
a=( *.@(tgz|tar.gz) )
if [[ ${#a} -ne 0 ]]; then …

这是 zsh 的等效项。不区分大小写的匹配的前缀extended_glob需要该选项。 (#i)glob(N)限定符指示不匹配 glob 的空扩展。

setopt extended_glob
a=( (#i)*.(tgz|tar.gz)(N) )
if [[ ${#a} -ne 0 ]]; then …

答案2

您的示例没有提供有关您所比较的来源是什么的任何线索。如果你想列出当前目录中的文件,你可以将一些 glob 串在一起,如下所示:

for file in *.tgz *.tar.gz *.TGZ *.TAR.GZ; do
    echo $file
done

如果您想针对模式测试字符串中的文件名,请尝试以下操作:

if [[ ( $file =~ .*\.(tgz|TGZ|tar\.gz|TAR\.GZ) ) ]]; then
    echo $file
fi

或者您可以使用 case 语句:

case $file in
    *.tgz|*.tar.gz|*.TGZ|*.TAR.GZ)
        echo $file
        ;;
esac

答案3

您甚至可以仅使用 glob 表达式进行不区分大小写的匹配:

for f in *.[Tt][Gg][Zz] *.[Tt][Aa][Rr].[Gg][Zz]; do
   echo $f
done

相关内容