web-dev-qa-db-ja.com

Linuxの「スクリプト」コマンドの出力をクリーンアップする方法

Linuxの「スクリプト」コマンド http://www.linuxcommand.org/man_pages/script1.html を使用して、いくつかのインタラクティブセッションを追跡しています。からの出力ファイルには、バックスペースキーストロークなどの印刷できない文字が含まれています。

これらの出力ファイルを整理して、画面に表示されたものだけが含まれるようにする方法はありますか?

または、対話型シェルセッション(入力と出力)を記録する別の方法はありますか?

36
Andrew

ファイルを表示する場合は、col -bpを介して出力を送信できます。これは制御文字を解釈します。その後、必要に応じて、パイプを少なくすることができます。

col -bp TypeScript | less -R

一部のシステムでは、colはファイル名引数を受け入れません。代わりに次の構文を使用します。

col -bp <TypeScript | less -R
35
Arcege
cat TypeScript | Perl -pe 's/\e([^\[\]]|\[.*?[a-zA-Z]|\].*?\a)//g' | col -b > TypeScript-processed

Perlへの文字列入力の解釈は次のとおりです。

  • s/pattern//gは、全体を置換することを意味します(gオプションは、最初の置換で停止するのではなく、すべてを実行することを意味します)入力文字列

ここに正規表現パターンのいくつかの解釈があります:

  • \e特殊な「エスケープ」制御文字(ASCII 0x1A)に一致
  • ()はグループの始まりと終わりです
  • |は、グループがN個のパターンのいずれかに一致できることを意味します。ここで、Nパターンは
    • [^\[\]]または
    • \[.*?[a-zA-Z]または
    • \].*?\a
  • [^\[\]]はを意味します
    • nOT文字のセットに一致します。NOT文字は[および]です。
  • \[.*?[a-zA-Z]はを意味します
    • [で始まる文字列に一致し、最初のアルファベット文字まで貪欲でない.*?を実行します
  • \].*?\aはを意味します
    • ]で始まる文字列に一致し、「アラート(ベル)文字」と呼ばれる特殊な制御文字がヒットするまで、貪欲でない.*?を実行します
18
Peter Nore

col -bpは、必要に応じてバックスペースを処理します(AFAIK)。しかし、それはカラーエスケープシーケンスを壊します。最初にカラーシーケンスを削除してから、可能であればバックスペースを処理することをお勧めします。

これは非常に一般的なニーズであり、これに対する解決策がこれ以上ないことに驚きます。セッションをスクリプト化することは非常に一般的です。その場合、誰かが手順を確認する必要があります。小さな入力ミスをすべて取り除き、エスケープシーケンスに色を付けて、後で参照できるように手順の「クリーンな」スクリプトを作成します。単純なASCIIテキスト優先。これは「人間が読める」が意図するものであり、実行するのは非常に合理的なことだと思います。

2
Aaron

大量のscript出力の場合、Perlスクリプトを繰り返しハックします。それ以外の場合は、優れたエディターで手動で編集してください。

特定の重要な瞬間に画面に表示されたものを再現する方法でscript出力から制御文字を削除する既存の自動化された方法はほとんどありません(ホストがそれを待っているときなど)最初ユーザー入力の文字)。

たとえば、Andrew $を除いて画面に何も表示されない場合があります。次にrm /*と入力し、バックスペースを12回押すと(必要以上に)、画面の最後に表示される内容は、シェルが実行されていて、現在のstty設定が何であるか(セッションの途中で変更される可能性があります)、おそらく他のいくつかの要因もそうです。

上記は、入力と出力を継続的にキャプチャする自動化された方法に適用されます。主な代替手段は、「スクリーンショット」を撮るか、セッション中に適切な時間に画面をカットアンドペーストすることです(これは、ユーザーガイド、日誌のメモなどのために行うものです)。

2
RedGrittyBrick

Ifコマンドを記録する(たとえば、後でコマンドをbashスクリプトに変換する)場合は、script(1)を実行してから、その中で実行するのが妥当なハックです。

bash -x

その後、grepは、「+」で始まる行を探す出力ファイル(通常は「TypeScript」)を探します。正規表現^\+トリックを行います。

2
Yaron

私の質問の2番目の部分に対する答えは、gnu画面のロギング機能を使用することです:^A H実行中のスクリーンセッション内から。ドキュメントは http://www.gnu.org/software/screen/manual/screen.html#Logging にあります

2
Andrew

cat filenameは制御文字を削除します:-)

2
Peeyush

出力をファイルに書き込みたい場合:

col -bp < TypeScript >>newfile

必要に応じて、unix2dosコマンドを使用してファイルをWindows形式に変換します

2
amara

https://github.com/RadixSeven/TypeScript2txt は、この問題を解決するために作成されました。

私が最後に更新/使用してから4年になりますが、今日はまだ機能しないはずの奇妙なことをした覚えはありません。

1
Eponymous

Perlが利用できる環境にいる場合、Unixボードの同様の質問に対して dewtallが提供した回答 が、スクリプトの出力から制御文字を削除するのにより効果的であることがわかりました。

dewtallのスクリプト:

#!/usr/bin/Perl
while (<>) {
    s/ \e[ #%()*+\-.\/]. |
       \r | # Remove extra carriage returns also
       (?:\e\[|\x9b) [ -?]* [@-~] | # CSI ... Cmd
       (?:\e\]|\x9d) .*? (?:\e\\|[\a\x9c]) | # OSC ... (ST|BEL)
       (?:\e[P^_]|[\x90\x9e\x9f]) .*? (?:\e\\|\x9c) | # (DCS|PM|APC) ... ST
       \e.|[\x80-\x9f] //xg;
       1 while s/[^\b][\b]//g;  # remove all non-backspace followed by backspace
    print;
}

制御文字を削除するには:

./dewtalls-script.pl < output-from-script-that-needs-control-characters-removed
1
rynemccall

私はそれを行う良い方法を見つけました。私のシステムでは、長い出力行には "^ M"(空白の後に改行が続く)が散りばめられています。 「^ M」はヌル文字「^ @」でうまく置き換えることができ、ファイルをcatしたときにまったく表示されません。

私もタイミングをキャプチャしているため、ファイルを完全に再生するために、以下のコマンドを使用して "^ M"を完全に削除することはできません(scriptreplayはバイトをカウントするため)。

tr '\r' '\0' | sed 's/ \x0//g'

次のようにスクリプトコマンドを実行します。

script -t -f session.log 2>timing

だから、私が後でやることは:

cat session.log | tr '\r' '\0' > TypeScript 
scriptreplay -t timing | sed 's/ \x0//g'

最初の編集(再生前)では、ファイルのバイト数が保持されます。 2番目の編集(再生後)は、ランダムな場所の空白を取り除きます。 (デフォルトでは、scriptreplayは「TypeScript」という名前の入力ファイルを検索するため、「タイミング」の後に提供しなかったので注意してください。)

0
Khanan