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

答え2

結果に応じて、次の操作を行います。

ls|awk -F"-" '{print $2}'

t-うまくいきますが、この部分を検討したい場合

ls|grep ^t-|awk -F"-" '{print $2}'

または

ls|awk -F"t-" '{print $2}'|awk -F"-" '{print $1}'

答え3

あなたの例に基づいてファイルリストを作成するときは、ls次のようにソートします。

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

したがって、次のbash関数はファイルの改行文字と番号を同じ順序で出力します。

改行とt-と2番目の間の数字を除くすべてのテキストを削除したいと思います。

これに対する私の解釈は、一致しないファイル名はt-「改行を除いて削除」する必要があるということです。つまり、これらのファイル名に対して空行を出力しますが、そうでない場合はダッシュ間の数字を出力します。

lsnums ()
{
    for f in *
    do
        if [[ "$f" =~ t-([[:digit:]]+)- ]]; then
            printf '%s\n' "${BASH_REMATCH[1]}"
        else
            echo
        fi
    done
}

結果の出力は次のとおりです。

$ lsnums


1
21
3
42

...ここで、2つの空行はmy代わりに始まる最初のファイルタイプに対応しますt-

答え4

これは次のように簡単に行うことができます。

ls | cut -d '-' -f 2

関連情報