数千文字より長い行を含む一部のJSONファイルを特定する必要があります。一致する項目の左右に最大N文字までコンテキストを表示するようにgrepを制限するにはどうすればよいですか?一般的なLinuxパッケージで利用可能な限り、grep以外のすべてのツールが利用可能です。
これは出力例です。仮想のgrepスイッチF:
$ grep -r foo *
hello.txt: Once upon a time a big foo came out of the woods.
$ grep -Ф 10 -r foo *
hello.txt: ime a big foo came of t
答え1
これを試してください:
grep -r -E -o ".{0,10}wantedText.{0,10}" *
- 金利拡張正規表現を使用するように指示します。
- モールド一致するものだけを印刷したいと言います。
-アル字型grep このフォルダで再帰的に結果を検索しています。
正規表現:
{0,10}印刷する任意の文字数を示します。
。すべての文字を表します(文字自体は重要ではなく、数字のみが重要です)。
編集する:ああそうですね。 Josephが推奨するソリューションは私とほぼ同じです。 :D
答え2
cut
標準出力をパイプするには、フラグを使用します-b
。 grep出力に1行に1〜400バイトのみを含めるように指示できます。
grep "foobar" * | cut -b 1-400
答え3
GNUの使用grep
:
N=10; grep -roP ".{0,$N}foo.{0,$N}" .
説明する:
-o
=>一致するものだけを印刷してください。-P
=> Perlスタイルの正規表現を使う- 正規表現は、
$N
0を文字と一致させ、0を文字foo
と一致させることを意味します。$N
GNUがない場合grep
:
find . -type f -exec \
perl -nle '
BEGIN{$N=10}
print if s/^.*?(.{0,$N}foo.{0,$N}).*?$/$ARGV:$1/
' {} \;
説明する:
私たちはもはやgrep
GNUに頼ることができないので、ファイルの再帰検索をgrep
使用します(GNUの仕事)。見つかった各ファイルに対してPerlコードを実行します。find
-r
grep
Perlスイッチ:
-n
ファイルを1行ずつ読み込む-l
各行の末尾の改行文字を削除して印刷するときに挿入します。-e
次の文字列をコードと見なしてください。
Perlのコードスニペットは、基本的にgrep
変数$N
を必要な数のコンテキスト文字に設定するのと基本的に同じです。つまり、BEGIN{}
ファイルの各行に対して一度だけ実行されるのではなく、実行開始時に一度だけ実行されます。
正規表現置換が有効な場合、各行で実行される文はその行を印刷します。
正規表現:
- line() 1 の先頭で古い項目との一致を遅らせ
^.*?
、この例と.{0,$N}
同じ場合、別の場合、最後に line() の終わりまで古い項目との一致を遅延します。grep
foo
.{0,$N}
.*?$
- は、現在読んでいるファイルの名前を保持する魔法変数に置き換えられます
$ARGV:$1
。括弧が一致するのはこの場合のコンテキストです。$ARGV
$1
foo
貪欲なマッチは、マッチに失敗することなく前の文字をすべて食べるので(.{0,$N}
ゼロのマッチが許可されるため)、両端で遅延マッチが必要です。
1つまり、完全一致が失敗しない限り、何も一致しないのが最善です。つまり、できるだけ少ない数の文字を一致させます。
答え4
ソース:http://www.topbug.net/blog/2016/08/18/truncate-long-matching-lines-of-grep-a-solution-that-preserves-color/ そして https://stackoverflow.com/a/39029954/1150462
".{0,10}<original pattern>.{0,10}"
強調色がしばしば混乱していることを除いて、提案されたアプローチは非常に良いです。同様の出力でスクリプトを作成しましたが、色も維持されました。
#!/bin/bash
# Usage:
# grepl PATTERN [FILE]
# how many characters around the searching keyword should be shown?
context_length=10
# What is the length of the control character for the color before and after the matching string?
# This is mostly determined by the environmental variable GREP_COLORS.
control_length_before=$(($(echo a | grep --color=always a | cut -d a -f '1' | wc -c)-1))
control_length_after=$(($(echo a | grep --color=always a | cut -d a -f '2' | wc -c)-1))
grep -E --color=always "$1" $2 | grep --color=none -oE ".{0,$(($control_length_before + $context_length))}$1.{0,$(($control_length_after + $context_length))}"
スクリプトがとして保存されていると仮定するgrepl
と、grepl pattern file_with_long_lines
一致する行を表示する必要がありますが、一致文字列の周囲には10文字だけが必要です。