grep --color=auto ^Mがカラーマッチ内にある場合は中断されます。

grep --color=auto ^Mがカラーマッチ内にある場合は中断されます。

The quick brown fox jumps\n over the lazy dog.テキストの行末が異なる2つの類似したファイル(dos.txtとunix.txt)があります。行末で単語を検索すると、dos.txtの出力が空になります。

$ grep -E 'jumps^M?$' dos.txt unix.txt

unix.txt:The quick brown fox jumps

Grepは何かを見つけましたが、印刷しません。 grepの実際の出力は次のとおりです。

$ grep -E --color=always 'jumps^M?$' dos.txt unix.txt | cat -v
^[[35m^[[Kdos.txt^[[m^[[K^[[36m^[[K:^[[m^[[KThe ... ^[[01;31m^[[Kjumps^M^[[m^[[K
^[[35m^[[Kunix.txt^[[m^[[K^[[36m^[[K:^[[m^[[KThe ... ^[[01;31m^[[Kjumps^[[m^[[K

したがって、唯一の違いは、^ Mがカラー出力の内側にあり、行全体が消えることです。 dos2unixなどのツールを使用してdosファイルを変換せずにこの問題を解決するにはどうすればよいですか?

答え1

エスケープシーケンスを検索した後、^[[K私は次の本を半冊読みました。VT100端子確認してみると、man grep環境変数をGREP_COLORS次のように設定したことがわかりました。

GREP_COLORS=ne

希望の出力を提供します。

$ export GREP_COLORS=ne
$ grep -E --color=always 'jumps^M?$' dos.txt unix.txt
dos.txt:The quick brown fox jumps
unix.txt:The quick brown fox jumps

$ grep -E --color=always 'jumps^M?$' dos.txt unix.txt | cat -v
^[[35mdos.txt^[[m^[[36m:^[[mThe ... ^[[01;31mjumps^M^[[m
^[[35munix.txt^[[m^[[36m:^[[mThe ... ^[[01;31mjumps^[[m

grepマニュアルページから:

ne     Boolean  value  that prevents clearing to the
       end of line using Erase in Line (EL) to Right
       (\33[K)  each  time  a  colorized  item ends.
       This is needed on terminals on  which  EL  is
       not  supported.   It  is  otherwise useful on
       terminals  for  which  the   back_color_erase
       (bce)  boolean  terminfo  capability does not
       apply, when the chosen  highlight  colors  do
       not  affect the background, or when EL is too
       slow or causes too much flicker.  The default
       is false (i.e., the capability is omitted).

私の場合は、ハイライトカラーを設定して背景色を変更してもうまくいきました。

export GREP_COLORS="ne:mt=41;38"

今興味深い質問は、なぜ^[[Kこの空行が生成されるのかということです。

文字は、^M次の行に移動せずにキャリッジリターンを表します。

$ echo -e "start^Mend"
endrt

^[[Kカーソルの右側の行を消去し、残りの行を書き込みます。

$ echo -e "start\033[Kend"
startend

^Mただし、前に入れると^[[K内容が削除されます。

$ echo -e "start^M\033[Kend"
end

書いた後スタートカーソルが行の先頭に移動し、すべての^[[K内容が削除され、残りの行が記録されます。grep出力の最初の行がすべてを単語に書き込む場合飛躍その後、行の先頭に戻り、^M無害な^[[mシーケンスを書き、^J新しい行に移動します。そのため、全行を消した後です^[[K^M

答え2

tr(1) を使用して出力をパイプし、キャリッジリターンを削除できます。 tr -d '\r'すべてのキャリッジリターンが削除されます。

これは働きます:

grep --color=always -E 'jumps' dos.txt unix.txt | tr -d '\r'

(にも適用されます^M?。)

ヒント:出力に安全でない文字が含まれる可能性があると思われる場合は、出力をless(1)にパイプしてください。

関連情報