lsの出力からパターンに一致する数値を取得しますか?

lsの出力からパターンに一致する数値を取得しますか?

フォルダがあり、lsそのフォルダから実行すると出力されます。

t-1-myFirstTest.c
myFile.c
t-42-my_second_test.c
t-3-test1234.c
  .
  .
  .
mySecondFile.c
t-21-tset241.c

t-改行文字と と second の間の数字を除くすべての内容をそのテキストから削除したいと思います-。したがって、前の出力の出力は次のようになります。

1
42
3
 .
 .
 .
21

解決策がありますが、かなり悪いと思います。私たちが話しているフォルダが実際に現在のディレクトリにある場合は、次のようにします。

ls | grep -o -E t-[0-9]+-[a-zA-Z0-9_]+.c | grep -o -E t-[0-9]+ | grep -o -E [0-9]+

同じことを行うより良い方法はありますか?

ベストアンサー1

出力を解析するのはls悪い考えです(出力はls見ることです)。質問参照」なぜ`ls`を解析しないのですか?」。

方法は次のとおりです/bin/sh

for filename in t-*-*.c; do
    [ ! -f "$filename" ] && continue
    number=${filename#t-}   # remove "t-" from start of filename
    number=${number%%-*}    # remove everything from first "-" in what remains
    printf '%s\n' "$number"
done

これは、名前がパターンと一致する現在のディレクトリのすべてのファイル名を繰り返しますt-*-*.c。各名前について、ビットt-は最初から削除され、2番目-以降のすべてのエントリは他のパラメータ拡張によって削除されます。

拡張は、次から${variable#word}(最も短い)一致を削除します。wordスタートof $variable、whileから${variable%%word}(最も長い)一致を削除します。word終わりひも。

bashファイル名と一致する正規表現を使用してください。

for filename in t-*-*.c; do
    [ ! -f "$filename" ] && continue
    if [[ "$filename" =~ ^t-([0-9]+)- ]]; then
        printf '%s\n' "${BASH_REMATCH[1]}"
    fi
done

t-これにより、各ファイル名で次の数字が一致してキャプチャされます。${BASH_REMATCH[1]}一致が正常に完了したら、キャプチャされた番号グループを使用できます。インデックスは、1正規表現の最初のキャプチャグループ(括弧)を表します。

遅いが潜在的に快適な(「使い慣れた」)ソリューションのために、外部コマンドを呼び出して興味のある文字列ビットを解析できます。

for filename in t-*-*.c; do
    [ ! -f "$filename" ] && continue
    cut -d '-' -f 2 <<<"$filename"
done

これはループから呼び出すことbashができると仮定します。cutこれは、シェル自体の組み込み操作を使用するよりもはるかに遅いです。ここのコマンドは、cut渡された文字列から2番目に区切られたフィールドを返すように要求されます(「here-string」リダイレクトを使用)。-bash

おすすめ記事