テキストファイルの行の先頭にある特定の検索文字列が最初に表示される行番号を見つけて、私のbashスクリプトの変数に保存する必要があります。たとえば、「c」が最初に表示されるものを探したいとします。
abc
bde
cddefefef // this is the line that I need its line number
Casdasd // C here is capital, I dont need it
azczxczxc
b223r23r2fe
Cssdfsdfsdf
dccccdcdcCCDcdccCCC
eCCCCCC
これを思い出しましたが、ご覧のように問題が大きいです。
trimLineNum=$(cat "${varFileLog}" | grep -m1 -n "c")
echo "c is at line #"${trimLineNum}
出力は次のとおりです。
c is at line #1:abc
質問:
- その行に「c」があるので、明らかに最初の行と一致します。
- 出力にはその行の内容も含まれます!私はそれが行番号だけでありたいです。
これらの問題を解決するには、何を変更する必要がありますか?
答え1
POSIXでは、sed
通常の出力を抑制するオプションを使用でき、-n
(pattern)で始まる行の場合とuitを使用して行番号を印刷できます。c
^c
=
q
sed -n '/^c/{=;q;}'
GNUを使用すると、コマンドをsed
使用して出力なしで終了し、次に単純化できます。Q
sed '/^c/!d;=;Q'
答え2
複数のソリューションが存在します
awkで
awk '/^c/ { print NR; exit}' "${varFileLog}"
/^c/
:次から始まる行と一致します。c
print NR
:レコード(ライン)番号の印刷exit
:処理を続行しません
予想通り、awk
これが私が好む解決策です。
grep + フィルタの使用
grep -n '^c' "${varFileLog}" | head -n1 | sed 's/:.*//'
'^c'
:次から始まる行と一致します。c
head -1
: grep 結果の最初の行のみを表示sed 's/:.*//'
:後で何でも削除:
sed 's/:.*//'
この場合もcut -d: -f1
同じ効果があります
パフォーマンス情報
Stephenのソリューションよりも遅くなる可能性があります。
grep -m1 -n '^c' "${varFileLog}" | cut -d: -f1
答え3
grep
一致を行の先頭に固定して、「行の先頭になければならない」制約を考慮する必要があります^
。
trimLineNum=$(grep -m1 -n -- '^c' "${varFileLog}")
その後、ポストプロセスの出力には行grep
番号のみが保持されます。
trimLineNum=$(grep -m1 -n -- '^c' "${varFileLog}")
trimLineNum="${trimLineNum%%:*}"
これは-m
GNU拡張です(GNUの場合、GNUはオプションではなく引数の後でもオプションを受け入れるため、偶数で始めるgrep
必要はありません)。標準的に出力を 。--
^c
--
$varFileLog
-
grep
head -n 1
一致するものがない場合、最初のコマンドはfalse / failを返し、2番目のコマンドはpipefail
複数のシェル(bash
。
答え4
使用幸せ(以前のPerl_6)
raku -ne 'state $i; ++$i; say "c starts line $i" and last if m/^c/;'
または
raku -ne 'state $i; ++$i; say "c starts line $i" and last if (.index("c").defined && .index("c") == 0);'
または
raku -ne 'state $i; ++$i; say "c starts line $i" and last if .starts-with("c");'
出力:
c starts line 3
-ne
Raku(ライン別非自動印刷)コマンドラインフラグを使用します。行番号を取得するには、state
変数を$i
一度初期化してから行を読むたびにインクリメントします。 "c"行の先頭が識別されると(正規表現または、index
またはでstarts-with
)文字列が"c starts line $i"
補間されて出力されます(say
)。
as last
注:上記の各例には、優先順位の低い条件が追加されました。一致するすべての行番号を返すには、この条件を削除してください。例:
~$ raku -ne 'state $i; ++$i; say "c starts line $i" if m/^c/;' file
c starts line 3
c starts line 10
付録:ありがとうこの回答、Rakuルーチンを使用して「c」で始まるゼロインデックスの最初の行番号を取得する簡単な方法は次のとおりですfirst
。
~$ raku -e 'say lines.first(* ~~ / ^ c /):k;' file
2
#OR
~$ perl6 -e 'say lines.first(*.starts-with("c")):k;' file
2
入力例:
abc
bde
cddefefef // this is the line that I need its line number
Casdasd // C here is capital, I dont need it
azczxczxc
b223r23r2fe
Cssdfsdfsdf
dccccdcdcCCDcdccCCC
eCCCCCC
cddefefef // this is the line that I need its line number (again)