仅返回 bash glob 的扩展部分

仅返回 bash glob 的扩展部分

假设我的目录包含文件 hesa1.c 和 hesa2.c。以下 bash 脚本

#!/bin/bash
for j in hes*.c
do
echo $j
done

返回 hesa1.c 和 hesa2.c 。

如何让这个 bash 脚本仅返回 a1 和 a2 (即通配符扩展为什么)?

答案1

这不是一个完全通用的答案,如“仅显示通配符扩展”,但您可以使用 shell 的参数扩展功能删除 glob 的固定部分:

j=${j#hes}
echo ${j%.c}

这会删除 开头的固定“hes” j,然后删除 结尾的固定“.c” j

答案2

Stephen 基于 shell 的方法可能是最简单的,但你也可以使用类似的东西sed

for j in hes*.c
do
    printf '%s\n' "$j" | sed -E 's/^hes(.*)\.c$/\1/'
done

答案3

这是您可以使用printf并对数组进行切片的另一种方法:

for f in hes*; do printf '%s\n' "${f[@]:3:-2}"; done

同样使用PE:

for f in hes*; do tmp="${f%.c}"; printf '%s\n' "${tmp:3}"; done

答案4

假设存在一个*,我们可以编写一个 Perl 脚本expandstar来扩展它

#!/usr/bin/perl
my $a=shift;                               ## a='he*.c'  for example
my $b=($a=~s/\*/(.*)/gr);                  ## b='he(.*).c'
for( glob($a)){                            ## for all files matching a
   print s/$b/$1/r ,"\n"                   ##   print after substituting
}

用法:

$ expandstar 'he*.c'                       ## dont forget '...'
sa1
sa2

如果您更喜欢在线用户(为您感到羞耻):

perl -E '$a=$b=shift; $b=~s/\*/(.*)/; say s/$b/$1/r for glob($a)' 'he*.c'

相关内容