リダイレクトされたときにclangが判読できないテキストを生成するのはなぜですか?


20

コマンドの出力をファイルに保存しようとしています。コマンドは次のとおりです。

clang -Xclang -ast-dump -fsyntax-only main.cpp > output.txt

ただし、(ubuntuでgeditとjeditによって)開かれたときの結果のoutput.txtファイルは、これを私に与えます:

[0;1;32mTranslationUnitDecl[0m[0;33m 0x4192020[0m <[0;33m<invalid sloc>[0m> [0;33m<invalid sloc>[0m
[0;34m|-[0m[0;1;32mTypedefDecl[0m[0;33m 0x4192558[0m <[0;33m<invalid sloc>[0m> [0;33m<invalid sloc>[0m implicit[0;1;36m __int128_t[0m [0;32m'__int128'[0m
[0;34m| `-[0m[0;32mBuiltinType[0m[0;33m 0x4192270[0m [0;32m'__int128'[0m
[0;34m|-[0m[0;1;32mTypedefDecl[0m[0;33m 0x41925b8[0m <[0;33m<invalid sloc>[0m> [0;33m<invalid sloc>[0m implicit[0;1;36m __uint128_t[0m [0;32m'unsigned __int128'[0m
[0;34m| `-[0m[0;32mBuiltinType[0m[0;33m 0x4192290[0m [0;32m'unsigned __int128'[0m
...

本当に次のようになるはずです:

TranslationUnitDecl 0x4e46020 <<invalid sloc>> <invalid sloc>
|-TypedefDecl 0x4e46558 <<invalid sloc>> <invalid sloc> implicit __int128_t '__int128'
| `-BuiltinType 0x4e46270 '__int128'
|-TypedefDecl 0x4e465b8 <<invalid sloc>> <invalid sloc> implicit __uint128_t 'unsigned __int128'
| `-BuiltinType 0x4e46290 'unsigned __int128'
...

私はそれがエンコーディングの問題かもしれないと思ったので、file -bi output.txt出力するファイルのエンコーディングをチェックしましたtext/plain; charset=us-ascii

エンコーディングをutf-8に変更すると問題が修正されると考えたので、これを試しました:

clang -Xclang -ast-dump -fsyntax-only main.cpp | iconv -f us-ascii -t UTF-8 > output.txt

しかし、違いはありませんでした。

この問題を解決するにはどうすればよいですか?

問題は、構文が強調表示されたバージョンを表示しようとしているということではありません(そもそもそれを表示するのに問題はありませんでした)。clangによって生成されたASTをファイルに保存してから解析する必要がありますが、色情報が残っていると難しいでしょう。


4
>出力を生成せずclang、ターミナルではなく、指定されたファイルにコマンドの出力を配置することを単にシェルに指定することに注意してください。その後、同じ方法でカラーコードを許可しない方法で表示しています。あなたがした場合cat、ファイルには、端末として働くだろう引き継ぐだろう、とあなたが作ることができるlessと同じことを行う-Rフラグ。
サミッチ



@Scott-出力を表示しようとせず、色情報を残さずにファイルに保存しようとしています。これにより、ファイルの解析が不必要に複雑になります。
-maou

回答:


54

コードページ/エンコードとは関係ありません。出力はプレーンテキストではありません。のようなシーケンスが含まれています[0;1;32m。これらの文字列(表示されない[エスケープ]文字もこれらの各文字の前にあります)は、太字、斜体、さまざまな色などでテキストを表示するための端末への指示です。それをサポートします。

clangに出力の美化を試みず、代わりにプレーンテキストを使用するように指示するオプションが必要です。マニュアルを確認してください。(私には便利なものがないので、適切なコマンドが何であるかを伝えることはできません。)


15
おかげで、それが原因でした。試したところclang -Xclang -ast-dump -fsyntax-only -fno-color-diagnostics main.cpp > output.txt、正しい出力が得られました。
maou

9
Clangが適切に動作する場合(チェックせずに端末コードを送信する場合は明らかにそうではありません)、別の修正方法isatty(stdout)TERM(例えば)に設定することdumbです。
トビー・スペイト

4
「端末がサポートしている場合、これにより出力が読みやすくなります。」つまり、意見です。たとえば、色付けアプリが黒の背景に濃い青色のテキストを出力する場合など、常にそのように動作するとは限りません:
jamesqf

4
合理的なソフトウェアは、その出力がファイルにリダイレクトされていることを検出し、その場合は色付けをオフにする必要があります。
n0rd

1
@ n0rd理想的にはそうですが、リダイレクトされた出力でisattty()がfalseを与えられない状況が十分に見られます。また、場合によっては、ユーザーはエスケープコードをリダイレクトしたい場合があります(たとえば、後で表示するか、netcatにパイプして別のシステムで表示し、2つのユースケースを表示するだけです)。そのため、推測を試みますが、ユーザーが間違っていた場合に推測を無効にしてオン/オフにすることもできます。それが最善の解決策です。
トニー

12

あるいは、出力から色を削除する代わりに、以下のrawオプションを使用して、ターミナルで色付きの出力を表示できます。 less

less -r output.txt

2

これらの文字は、[0;33m私にとっては端末出力制御のように見えます。これらは、ターミナル内のテキストに色を適用するために頻繁に使用される一連のエスケープシーケンスの一部です。このような生の状態では、bashプロンプト自体に色を適用するためにもよく使用されます。これ.bashrcは、すべてのマシンで長年使用してきたものです。

export PS1='\[\033[1;33m\]\u\[\033[1;35m\]@\[\033[1;32m\]\h\[\033[0;36m\]\w\[\033[1;37m\]\$ \[\033[0;37m\]'

(ほとんどが見苦しいと思いますが、私は気に入っています)。

コマンドの出力から色分けなどを削除するスイッチを見つけることができるかどうかを確認し、それが役立つかどうかを確認します。


13
[...]「bashの出力制御のように見えます」bashとは何の関係もありません。それが目的の端末です。
-glglgl

1
@glglglが言ったように、それらはBash固有ではなく、xterm関連するものです。参照してください。この素晴らしい答えをのリード開発者によってxterm

@glglglよし、それに応じて回答を編集しました。数年前にfBSDからlinuxに移行したときに初めて見ました。これはbashを使い始めたときでもあったので、後者の製品だと思いました。
ヤルムン
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.