フォルダがあり、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