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