再帰パターン検索 - 出力形式:一致するファイルごとに、特定のファイル名「\ n」、行番号、および色一致「¥ n」文を印刷します。

再帰パターン検索 - 出力形式:一致するファイルごとに、特定のファイル名「\ n」、行番号、および色一致「¥ n」文を印刷します。

Linuxでは、次のファイルコンテンツ検索コマンドが必要です。

  1. md、txt、htm などの指定されたファイルを検索します。
  2. フォルダとそのサブフォルダで繰り返し実行します(例:)。
  3. コンテンツ検索は正規表現パターンである可能性があります(例:tomat。* es)。
  4. 一致する項目の周囲のテキストを出力します。
  5. 出力は次の形式です。、各ファイルを空行で区切ります。
file1
lineNr1:text1
lineNr2:text2

file2
lineNr1:text1
lineNr2:text2

6/最後の基準である出力は視覚的に明確でなければなりません。したがって、端末でgrepなどのカラースキームを使用してください。

  • ファイルの色はcolor_1(紫色など)です。
  • color_2のlineNr(例:緑)
  • テキスト出力の場合:
    • color_3のテキストを一致させます(例:赤)。
    • 残りのテキストはcolor_4です(たとえば、白)。

もともと、grepはこれを行いますが、出力形式を変更したいと思います。、今すぐ:

file1:lineNr1:text1
file1:lineNr2:text2

file2:lineNr1:text1
file2:lineNr2:text2

私が望むのは検索結果に集中することですが、ディレクトリ検索を行うときに検索結果の前にファイルパス名があると検索がより複雑になります。ファイルに一致する項目が複数ある場合。私が望むのは、各ファイルが自分が探しているものを直接見ることができることです。ファイル、サブフォルダ、一致が多いほど、明確なフォーカスが重要になります。

したがって、grepは長い出力を提供し、フォーカスを失います。おそらくgrepコマンドの新機能として要求する必要があります。

欲しいものに近いです。

test.txtに次の2つの文があるとします。

2023-09-25: after colon char does not output the sentence.
2023-09-25 outputs line as there is NO colon preceding match.

次に、次のcliを実行します。

grep -rwn --include=\*.{md,txt} -ie "output.*" --color=always | awk -F: '{if(f!=$1)print "\n"$1; f=$1; print $2 ":" $3;}'

この例では、1行目の出力は「:」で停止し、2行目では美しい出力が表示されます。添付ファイルを参照ここに画像の説明を入力してください。

したがって、一致するテキストにコロン ":" が含まれていない場合、このクエリは操作を実行します。一致の周りにテキスト出力がないため、検索出力の使い勝手が悪くなります。

より複雑な例(txtファイルを添付できません):

    utf-8 encoded

#        We're interested in searching on the word: tomato or tomate in french
In markdown file it can be put in bold using **tomatoes**
In a html file, content is full of tags, put a word in bold can be put in many way, such as <b>tomato</b>

Let's see what the search will return on these combinations:
1. At 6:45 will eat tomato soup.
2. Tomatoes were cooked for the soup recipe, but what time do we eat tomato soup? Isn't it six forty-five, aka 6:45?
3. Tomate en français
4. tomates: pluriel du mot tomate.
Could be tricky to restrict search only on bilingual TOMATO's variation, as for instance in automatically, there is auTOMATically.
Regular expression are of help.

一致が2つのサブフォルダにあると仮定すると、このCLIは次のように明確に説明します。

grep -rn --include=\*.{md,txt} -iP "tomat[eo]s*" --color=always | awk -F: '{if(f!=$1)print "\n"$1; f=$1; print $2 ":" $3;}'

ただし、追加出力コロン文字 ":" 以降の内容は出力には現れません。、コロン ":" を ";" に変更すると、違いを見ることができます。 ここに画像の説明を入力してください。

grep出力と比較 ここに画像の説明を入力してください。

出力検索結果をプレーンテキストファイルにダンプしようとすると、カラースキームが失われると視覚情報が失われます。したがって、タグを含むhtmlファイルは色情報を回復します。これは、次のhtml出力で実行できます。:

<div class="grep">
<p class="grep_file">file_1</p>
<span class="grep_line">lineNr1</span>:beginning of surrounding match<span class="grep_match">SEARCH_PATTERN</span>end of surrounding match<br>
<span class="grep_line">lineNr2</span>:beginning of surrounding match<span class="grep_match">SEARCH_PATTERN</span>end of surrounding match<br>
</div>

<div class="grep">
<p class="grep_file">file_2</p>
<span class="grep_line">lineNr1</span>:beginning of surrounding match<span class="grep_match">SEARCH_PATTERN</span>end of surrounding match<br>
<span class="grep_line">lineNr2</span>:beginning of surrounding match<span class="grep_match">SEARCH_PATTERN</span>end of surrounding match<br>
</div>

スタイルクラスでカラースキームを取得できます。

さて、grepとawkを試してみましたが、他の組み合わせが仕事にとってより良いアイデアかもしれません。

ありがとう

答え1

考えるあなたが望むものは次のとおりです。

$ grep -rwn --include=\*.{md,txt} -ie "output.*" --color=always | awk -F: '{if(f!=$1){print "\n"$1;}f=$1; $1=""; }1'

file.txt
 1 2023-09-25  after colon char does not output the sentence.
 2 2023-09-25 outputs line as there is NO colon preceding match.

file1.txt
 1 2023-09-25  after colon char does not output the sentence.
 2 2023-09-25 outputs line as there is NO colon preceding match.

次のようになります。

色を示す上記のコマンド結果のスクリーンショット

アプローチの問題は、:フィールド区切り文字として使用し、フィールド2と3のみを明示的に印刷することです。したがって、:行にさらに多くのフィールドがある場合は、残りのフィールドを見逃す可能性があります。ここで行うことは、最初のフィールド($1="")をクリアしてから行全体を印刷することです(1;行を印刷します)。awk1

awkわかりやすくするために、コードを次のように拡張できます。

awk -F: '
 {
   ## If this is a new file name, print the file name
   if ( f != $1 ){
     print "\n"$1
   }
   ## save the 1st field in the variable f
   f=$1
   ## clear the first field
   $1=""
   ## print the line
   print
}'

重要:ファイル名自体に:file:weird.txtこれを処理することは可能ですが、より多くのスクリプトが必要なので、これが問題の場合は、より多くのサンプルファイル名を含めるように質問を更新するか、新しい質問を投稿してください。

答え2

このコマンドを使用すると、以下を提供できます。

grep -rwn --include=\*.{md,txt} -ie "output.*" --color=always |
    awk -F: '{if(f!=$1)print "\n"$1; f=$1; print $2 ":" $3;}'

output.*ファイル内の大文字または小文字に一致する文字列を含めるか、次に終わる行を検索しようとしているようです。それは:.md.txt

find . -type f \( -name '*.md' -o -name '*.txt' \) -exec \
    grep -Hin 'output' \
{} +

その後、その出力をawkにパイプすると、再びこの出力が変更されます。

file1:lineNr1:text1
file1:lineNr2:text2
file2:lineNr1:text1
file2:lineNr1:text2

これに関して:

file1
lineNr1:text1
lineNr2:text2

file2
lineNr1:text1
lineNr2:text2

したがって、画面に印刷を実装するのに役立つ必要があるものは次のとおりです。

$ grep -rwn --include=\*.{md,txt} -ie "output.*" --color=always |
    awk -F':' '{p=f; f=$1; sub(/[^:]+:/,"")} f!=p{print sep f; sep=ORS} 1'
test.txt
1:2023-09-25: after colon char does not output the sentence.
2:2023-09-25 outputs line as there is NO colon preceding match.

ここに画像の説明を入力してください。

grepただし、結果を読み取るときに結果の色を指定するために使用されたASCIIエスケープシーケンスがすでに出力に存在するため、awkASCIIエスケープシーケンスの代わりにHTMLタグを生成するには、それを含めるようにawkスクリプトを更新する必要があります。入力これらのエスケープシーケンスを見つけてHTMLタグに変換します。これは少し遅くて壊れやすいです(例:いくつかのエスケープシーケンスが元の入力に存在する場合はどうなりますか?これらのエスケープシーケンスと次のように追加されたものを区別する方法はありません。grep)vs。元の入力ファイルでgrepの代わりにawkを実行し、awkに希望のカラー文字列を印刷させます。

必要なレイアウトで無色テキストを印刷するには、find + grepの出力をawkにパイプするのではなく、grepをawkに置き換えることができます。

find . -type f \( -name '*.md' -o -name '*.txt' \) -exec \
    awk '
        tolower($0) ~ /output/ {
            if ( !seen[FILENAME]++ ) {
                print ORS FILENAME
            }
            print
        }
    ' \
{} +

出力に色を使用するには、awkスクリプトを更新してエスケープシーケンス、HTMLタグ、または目的の色、目的のテキストを印刷します。https://unix.stackexchange.com/a/669122/133219そしてhttps://stackoverflow.com/questions/64034385/using-awk-to-color-the-output-in-bash/64046525#64046525画面の色でこれを行う方法の詳細については、次を参照してください。https://stackoverflow.com/a/40722767/1745001そしてhttps://stackoverflow.com/a/39193330/1745001HTML出力に色を割り当てる方法を学びます。

以下は、bashスクリプトでfind + awkを使用して画面に印刷する出力形式を指定する例です。

$ cat tst.sh
#!/usr/bin/env bash
tput sc
trap 'tput rc; exit' EXIT

colors=( reset red green yellow blue purple )
for colorNr in "${!colors[@]}"; do
    fgColorMap+=( "${colors[colorNr]} $(tput setaf $colorNr)" )
done

find . -type f \( -name '*.md' -o -name '*.txt' \) -exec \
    awk -v fgColorMap="${fgColorMap[*]}" '
        BEGIN {
            OFS = ":"
            split(fgColorMap,tmp)
            for ( i=1; i in tmp; i+=2 ) {
                fg[tmp[i]] = tmp[i+1]
            }
        }

        match(tolower($0),/output.*/) {
            if ( !seen[FILENAME]++ ) {
                if ( found++ ) { print "" }
                print fg["purple"] FILENAME fg["reset"]
            }
            print fg["green"] FNR ":" fg["reset"]                  \
                  substr($0,1,RSTART-1)                           \
                  fg["red"] substr($0,RSTART,RLENGTH) fg["reset"] \
                  substr($0,RSTART+RLENGTH)
        }
        END { if ( found ) print "" }
    ' \
{} +

表示されるテキスト出力は次のとおりです。

$ ./tst.sh
./test.txt
1:2023-09-25: after colon char does not output the sentence.
2:2023-09-25 outputs line as there is NO colon preceding match.

これは同じですが、カラーコードが表示されます。

$ ./tst.sh | cat -A
^[7^[[35m./test.txt^[[30m$
^[[32m1:^[[30m2023-09-25: after colon char does not ^[[31moutput the sentence.^[[30m$
^[[32m2:^[[30m2023-09-25 ^[[31moutputs line as there is NO colon preceding match.^[[30m$
$
^[8$

カラー出力は次のとおりです。

![ここに画像の説明を入力してください。

HTMLを取得するには、awkスクリプトを変更して必要なHTMLを印刷します。質問に期待されるHTML出力が表示されないため、必要なものを表示していないため、必要なものを取得するのに役立ちません。ただし、使用できる既存の例がたくさんあります(参照I 'を参照)。上記の情報を提供しました)。したがって、どうすればよいかわからない場合は、後で新しい質問をしてください。

関連情報