文字列を解釈する端末の可視出力のみを取得します。

文字列を解釈する端末の可視出力のみを取得します。

空白以外の項目を含む列を表示するマスクを作成し、「空白のみ」の列を簡単に見つけるためのスクリプトを作成しています。

これを行うには、各行を「互いに重なる」として印刷し、スペースを「右矢印」に変更しました。 (別のステップは、「最後のヘッダーの先頭よりも長い列」の後に表示される空白を無視することですが、ここではこれはトピックではありません。)

<Esc>[C最後のステップ:生成/解釈に使用されているすべての\ r、\ n、および(=右矢印)を使用せずに結果文字列(私の端末が正しく表示する出力)を取得する方法に問題があります。

例:

$ PS2=""
$ Esc=$( printf '\033' )
$ Right=$( printf "${Esc}[C" )
$ ps | head -n 2
  PID TTY          TIME CMD
12415 pts/1160 00:00:00 bash
$ ps | head -n 2 | LC_ALL=C tr '!-~' '*'
  *** ***          **** ***
***** ******** ******** ****
$ ps | head -n 2 | LC_ALL=C tr '!-~' '*' | sed -e "s/ /${Right}/g" | while read line; do
    printf "%s\r" "$line"
  done ; printf '\n'
***** ******** ******** ****
  ## the line above is what I am looking for: 
  ## a "mask" of each column that at one point had a non-space character displayed in it
$ ( ps | head -n 2 | tr '!-~' '*' | sed -e "s/ /${Right}/g" | while read line; do
      printf "%s\r" "$line"
    done ; printf '\n'
  ) | cat -ve
^[[C^[[C***^[[C***^[[C^[[C^[[C^[[C^[[C^[[C^[[C^[[C^[[C^[[C****^[[C***^M*****^[[C********^[[C********^[[C****^M$
  ## but of course, the terminal sees (and outputs) this instead, which contains all the "contructing characters"

変数で「私の端末に示されているように」文字列を取得するにはどうすればよいですか?

***** ******** ******** ****

(全体の内容を " while read -e Finalstring; do print '[%s]' "$finalstring" ; did として出力しようとしましたが、FinalStringにはまだ "ポスト端末ではなく"事前解釈された"文字列全体が含まれています。しました」

同じ質問をする簡単な方法:

# if:
$ printf "aaaa\rbb\rc\n"
# displays:
cbaa
$ var=$( printf "aaaa\rbb\rc\n" ) # $var will be: "aaaa\rbb\rc\n"
# how can I instead have the resulting "displayed string": "cbaa" in $var ?

ベストアンサー1

まだターミナルエスケープを持っていないデータにターミナルエスケープを追加して追加の問題を生成するようです。必要なものがビジュアライゼーションの空の列だけである場合(ご存知のように)をps使用して、すべて空の列番号でインデックス付きの配列を累積し、必要に応じて「*」を取得できます。awkたとえば、

awk '
{ len = length($0)
  if(len>max)max = len
  for(i=1;i<=len;i++) if(substr($0,i,1)!=" ") col[i] = "*"
}
END{ for(i=1;i<=max;i++) if(col[i])str = str "*"; else str = str " ";
     print str
}'

おすすめ記事