bash globの拡張部分のみを返す[重複]

bash globの拡張部分のみを返す[重複]

私のディレクトリに hesa1.c と hesa2.c ファイルが含まれているとしましょう。 Next bash スクリプト

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

hesa1.c と hesa2.c を返します。

このbashスクリプトがa1とa2のみを返すようにするにはどうすればよいですか(つまり、ワイルドカード拡張の使用)。

答え1

これは「ワイルドカード拡張のみを表示」のような完全に一般的な答えではありませんが、パラメータ拡張機能グローブの固定部分を取り外します。

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

これにより、最初に固定された「hes」が削除され、j最後に固定された「.c」が削除されますj

答え2

Stephenのシェルベースのアプローチおそらく最も簡単かもしれませんが、次のものを使用できます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

1つが存在すると仮定すると、*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'

関連情報