印刷できない文字を検索しています。TLDR; エグゼクティブサマリー
- 制御文字と拡張ユニコードの検索
- ロケール設定など
LC_ALL=C
、grepが拡張Unicodeで期待することを実行するために必要
SO優先の非ASCII文字ファインダー:
$ perl -ne 'print "$. $_" if m/[\x00-\x08\x0E-\x1F\x80-\xFF]/' notes_unicode_emoji_test
上の答えのように、逆grep:
$ grep --color='auto' -P -n "[^\x00-\x7F]" notes_unicode_emoji_test
トップの回答と同じですが、WITH LC_ALL=C
:
$ LC_ALL=C grep --color='auto' -P -n "[\x80-\xFF]" notes_unicode_emoji_test
。。もっと 。。これについては耐え難いほどの詳細:。。
私はコメントの中に埋められた上記のHarveyに同意します。印刷不可能な文字を検索する方が多くの場合、または本当に印刷不可と考える必要があるときに非ASCIIと考えるのは簡単です。Harveyは「これを使用する:」を提案してい[^\n -~]
ます。DOSテキストファイルに\ rを追加してください。これは「[^\x0A\x020-\x07E]
」に、CRの場合は\ x0Dを追加します
また、-c(一致したパターンの数を表示)をgrepに追加すると、一致しない文字列が端末を混乱させる可能性があるため、印刷できない文字を検索するときに役立ちます。
範囲0-8と0x0e-0x1fを(0x80-0xffの範囲に)追加すると便利なパターンです。これには、TAB、CR、LF、および1つまたは2つ以上の一般的でない印刷可能な文字は含まれません。したがって、IMHOは非常に便利な(大雑把ではありますが)grepパターンです。
grep -c -P -n "[\x00-\x08\x0E-\x1F\x80-\xFF]" *
実際には、一般的にこれを行う必要があります:
LC_ALL=C grep -c -P -n "[\x00-\x08\x0E-\x1F\x80-\xFF]" *
壊す:
LC_ALL=C - set locale to C, otherwise many extended chars will not match (even though they look like they are encoded > 0x80)
\x00-\x08 - non-printable control chars 0 - 7 decimal
\x0E-\x1F - more non-printable control chars 14 - 31 decimal
\x80-1xFF - non-printable chars > 128 decimal
-c - print count of matching lines instead of lines
-P - perl style regexps
Instead of -c you may prefer to use -n (and optionally -b) or -l
-n, --line-number
-b, --byte-offset
-l, --files-with-matches
たとえば、findを使用して現在のディレクトリにあるすべてのファイルをgrepする実用的な例:
LC_ALL=C find . -type f -exec grep -c -P -n "[\x00-\x08\x0E-\x1F\x80-\xFF]" {} +
場合によっては、grepを調整することもできます。たとえば、一部の印刷可能なファイルで使用されるBS(0x08-バックスペース)文字、またはVT(0x0B-垂直タブ)を除外するため。BEL(0x07)およびESC(0x1B)文字も、場合によっては印刷可能と見なされます。
Non-Printable ASCII Chars
** marks PRINTABLE but CONTROL chars that is useful to exclude sometimes
Dec Hex Ctrl Char description Dec Hex Ctrl Char description
0 00 ^@ NULL 16 10 ^P DATA LINK ESCAPE (DLE)
1 01 ^A START OF HEADING (SOH) 17 11 ^Q DEVICE CONTROL 1 (DC1)
2 02 ^B START OF TEXT (STX) 18 12 ^R DEVICE CONTROL 2 (DC2)
3 03 ^C END OF TEXT (ETX) 19 13 ^S DEVICE CONTROL 3 (DC3)
4 04 ^D END OF TRANSMISSION (EOT) 20 14 ^T DEVICE CONTROL 4 (DC4)
5 05 ^E END OF QUERY (ENQ) 21 15 ^U NEGATIVE ACKNOWLEDGEMENT (NAK)
6 06 ^F ACKNOWLEDGE (ACK) 22 16 ^V SYNCHRONIZE (SYN)
7 07 ^G BEEP (BEL) 23 17 ^W END OF TRANSMISSION BLOCK (ETB)
8 08 ^H BACKSPACE (BS)** 24 18 ^X CANCEL (CAN)
9 09 ^I HORIZONTAL TAB (HT)** 25 19 ^Y END OF MEDIUM (EM)
10 0A ^J LINE FEED (LF)** 26 1A ^Z SUBSTITUTE (SUB)
11 0B ^K VERTICAL TAB (VT)** 27 1B ^[ ESCAPE (ESC)
12 0C ^L FF (FORM FEED)** 28 1C ^\ FILE SEPARATOR (FS) RIGHT ARROW
13 0D ^M CR (CARRIAGE RETURN)** 29 1D ^] GROUP SEPARATOR (GS) LEFT ARROW
14 0E ^N SO (SHIFT OUT) 30 1E ^^ RECORD SEPARATOR (RS) UP ARROW
15 0F ^O SI (SHIFT IN) 31 1F ^_ UNIT SEPARATOR (US) DOWN ARROW
更新:私はこれを最近再検討しなければなりませんでした。また、YYMVは端末の設定/太陽天気予報によって異なります。。grepが多くのUnicodeまたは拡張文字を見つけていないことに気づきました。直感的には0x80から0xffの範囲と一致するはずですが、3バイトと4バイトのUnicode文字は一致しませんでした。??? 誰かがこれを説明できますか?はい。@frabjousが尋ね、@ calandoaはLC_ALL=C
、コマンドのロケールを設定してgrepを一致させるために使用する必要があることを説明しました。
たとえば、私のロケールはLC_ALL=
空です
$ locale
LANG=en_IE.UTF-8
LC_CTYPE="en_IE.UTF-8"
.
.
LC_ALL=
LC_ALL=
空のgrepは、2バイトのエンコードされた文字に一致しますが、3バイトと4バイトのエンコードされた文字には一致しません。
$ grep -P -n "[\x00-\x08\x0E-\x1F\x80-\xFF]" notes_unicode_emoji_test
5:© copyright c2a9
7:call underscore c2a0
9:CTRL
31:5 © copyright
32:7 call underscore
grep with LC_ALL=C
は、必要なすべての拡張文字に一致するようです。
$ LC_ALL=C grep --color='auto' -P -n "[\x80-\xFF]" notes_unicode_emoji_test
1:���� unicode dashes e28090
3:��� Heart With Arrow Emoji - Emojipedia == UTF8? f09f9298
5:� copyright c2a9
7:call� underscore c2a0
11:LIVE��E! ���������� ���� ���������� ���� �� �� ���� ���� YEOW, mix of japanese and chars from other e38182 e38184 . . e0a487
29:1 ���� unicode dashes
30:3 ��� Heart With Arrow Emoji - Emojipedia == UTF8 e28090
31:5 � copyright
32:7 call� underscore
33:11 LIVE��E! ���������� ���� ���������� ���� �� �� ���� ���� YEOW, mix of japanese and chars from other
34:52 LIVE��E! ���������� ���� ���������� ���� �� �� ���� ���� YEOW, mix of japanese and chars from other
81:LIVE��E! ���������� ���� ���������� ���� �� �� ���� ���� YEOW, mix of japanese and chars from other
このperlの一致(部分的にstackoverflowのどこかで見つかります)または上位の回答の逆grepは、ロケールを設定せずに〜weird〜と〜wonderful〜のすべての「非ASCII」文字を見つけます。
$ grep --color='auto' -P -n "[^\x00-\x7F]" notes_unicode_emoji_test
$ perl -ne 'print "$. $_" if m/[\x00-\x08\x0E-\x1F\x80-\xFF]/' notes_unicode_emoji_test
1 ‐‐ unicode dashes e28090
3 💘 Heart With Arrow Emoji - Emojipedia == UTF8? f09f9298
5 © copyright c2a9
7 call underscore c2a0
9 CTRL-H CHARS URK URK URK
11 LIVE‐E! あいうえお かが アイウエオ カガ ᚊ ᚋ ซฌ आइ YEOW, mix of japanese and chars from other e38182 e38184 . . e0a487
29 1 ‐‐ unicode dashes
30 3 💘 Heart With Arrow Emoji - Emojipedia == UTF8 e28090
31 5 © copyright
32 7 call underscore
33 11 LIVE‐E! あいうえお かが アイウエオ カガ ᚊ ᚋ ซฌ आइ YEOW, mix of japanese and chars from other
34 52 LIVE‐E! あいうえお かが アイウエオ カガ ᚊ ᚋ ซฌ आइ YEOW, mix of japanese and chars from other
73 LIVE‐E! あいうえお かが アイウエオ カガ ᚊ ᚋ ซฌ आइ YEOW, mix of japanese and chars from other
SO優先の非ASCII文字ファインダー:
$ perl -ne 'print "$. $_" if m/[\x00-\x08\x0E-\x1F\x80-\xFF]/' notes_unicode_emoji_test
上の答えのように、逆grep:
$ grep --color='auto' -P -n "[^\x00-\x7F]" notes_unicode_emoji_test
トップの回答と同じですが、WITH LC_ALL=C
:
$ LC_ALL=C grep --color='auto' -P -n "[\x80-\xFF]" notes_unicode_emoji_test