特殊文字を評価せずにファイルの内容を印刷するにはどうすればよいですか?

特殊文字を評価せずにファイルの内容を印刷するにはどうすればよいですか?

これはBashとLinuxに関する小さな質問です。などの特殊文字を含むファイルがあります\n\r特殊文字を使用せずにファイルを印刷しようとしています。たとえば、ファイルの内容があればhi \t hello(代わりに)そのまま印刷されますhi hello。使用してもcat file操作は完了しません。 man of catを見てみたところ、-Aオプションを使用できることがわかりました。以下を印刷しますabc^Mabc。しかし、何ですか^M?表として印刷するにはどうすればよいですか\<char>

ベストアンサー1

ファイルに文字通りエスケープされた文字が含まれている場合(例:「こんにちは\n」バックスラッシュと「t」文字があるということは、タブ文字がなければならず、スラッシュと「n」が改行文字でなければならないことを意味します。その後、この表記法を解釈して実際の文字に変換する必要があります。

[Paul Pedantが指摘したように、echoを使用した以前のソリューションは機能しませんでした。]

いくつかのテストの後、Bashでリテラルエスケープ文字を引用解除する簡単な方法を考えました。

x="$(cat filename)"
echo -en "$x"

動作を確認するためにこのファイルを作成しました(次の行をcat > filename入力し、Ctrl-D Enter最後の行に5つの空白を入力して他の場所にCtrl-D Enterファイルを閉じます)。

    This line starts with 4 leading spaces, a tab here:\t. Has a real newline (RN) here:
Newline code here:\n, six spaces and a dot:      . RN:
Return code here:\r, because the return code the first three words are hidden in the terminal.RN:
  This line starts with two spaces, then has four and a tab here:    \tRN:
This final line ends with five spaces without an ending newline:     

このファイルに対して上記のコマンドを実行すると、戻りコードによって一部の行が上書きされ、タブの実際の幅が表示されないため、端末に奇妙な出力が表示されます。

出力で実際の文字を確認するには、8進ダンパに渡しますod

x="$(cat filename)"; echo -en "$x" | od -cx

-cが印刷できないエスケープ文字を表示し、-xが対応する16進コード(TAB = 09、RETURN = 0D、NEWLINE = 0A、SPACE = 20など)を表示する場合、結果は次のようになります。

0000000                   T   h   i   s       l   i   n   e       s   t
           2020    2020    6854    7369    6c20    6e69    2065    7473
0000020   a   r   t   s       w   i   t   h       4       l   e   a   d
           7261    7374    7720    7469    2068    2034    656c    6461
0000040   i   n   g       s   p   a   c   e   s   ,       a       t   a
           6e69    2067    7073    6361    7365    202c    2061    6174
0000060   b       h   e   r   e   :  \t   .       H   a   s       a
           2062    6568    6572    093a    202e    6148    2073    2061
0000100   r   e   a   l       n   e   w   l   i   n   e       (   R   N
           6572    6c61    6e20    7765    696c    656e    2820    4e52
0000120   )       h   e   r   e   :  \n   N   e   w   l   i   n   e
           2029    6568    6572    0a3a    654e    6c77    6e69    2065
0000140   c   o   d   e       h   e   r   e   :  \n   ,       s   i   x
           6f63    6564    6820    7265    3a65    2c0a    7320    7869
0000160       s   p   a   c   e   s       a   n   d       a       d   o
           7320    6170    6563    2073    6e61    2064    2061    6f64
0000200   t   :                           .       R   N   :  \n   R   e
           3a74    2020    2020    2020    202e    4e52    0a3a    6552
0000220   t   u   r   n       c   o   d   e       h   e   r   e   :  \r
           7574    6e72    6320    646f    2065    6568    6572    0d3a
0000240   ,       b   e   c   a   u   s   e       t   h   e       r   e
           202c    6562    6163    7375    2065    6874    2065    6572
0000260   t   u   r   n       c   o   d   e       t   h   e       f   i
           7574    6e72    6320    646f    2065    6874    2065    6966
0000300   r   s   t       t   h   r   e   e       w   o   r   d   s
           7372    2074    6874    6572    2065    6f77    6472    2073
0000320   a   r   e       h   i   d   d   e   n       i   n       t   h
           7261    2065    6968    6464    6e65    6920    206e    6874
0000340   e       t   e   r   m   i   n   a   l   .   R   N   :  \n
           2065    6574    6d72    6e69    6c61    522e    3a4e    200a
0000360       T   h   i   s       l   i   n   e       s   t   a   r   t
           5420    6968    2073    696c    656e    7320    6174    7472
0000400   s       w   i   t   h       t   w   o       s   p   a   c   e
           2073    6977    6874    7420    6f77    7320    6170    6563
0000420   s   ,       t   h   e   n       h   a   s       f   o   u   r
           2c73    7420    6568    206e    6168    2073    6f66    7275
0000440       a   n   d       a       t   a   b       h   e   r   e   :
           6120    646e    6120    7420    6261    6820    7265    3a65
0000460                  \t   R   N   :  \n   T   h   i   s       f   i
           2020    2020    5209    3a4e    540a    6968    2073    6966
0000500   n   a   l       l   i   n   e       e   n   d   s       w   i
           616e    206c    696c    656e    6520    646e    2073    6977
0000520   t   h       f   i   v   e       s   p   a   c   e   s       w
           6874    6620    7669    2065    7073    6361    7365    7720
0000540   i   t   h   o   u   t       a   n       e   n   d   i   n   g
           7469    6f68    7475    6120    206e    6e65    6964    676e
0000560       n   e   w   l   i   n   e   :
           6e20    7765    696c    656e    203a    2020    2020
0000576

何も失われず、コードは必要な単一文字に変換されます。

問題: Bash 変数の最大長が約 32k であるため、この単純な操作は小さなファイルのみ変換します。これを拡張するには、適切なサイズのチャンクでファイルを読み取って変換するループを作成する必要があります。ブロック読み取りのこの部分で選択するユーティリティはですdd。以下は、ブロックサイズが16k(16384)のこの方法を使用するフルコンバータスクリプトです。

#!/bin/bash
# unescape.sh: converts escaped chars (\t) to actual chars (TAB)
# 2020.11.19 Fjor
#-------------------------------
[ -z "$2" ] \
    && echo "Use: $0 inputfile outputfile  to unescape chars (\t -> TAB)" \
    && exit
IFILE="$1"
OFILE="$2"

#-- exists input file?
[ ! -r "$IFILE" ] \
    && echo "$0: Can't read inputfile $IFILE" \
    && exit

#-- don't destroy existing output file
[ -f "$OFILE" ] \
    && read -p "$0: Output file $OFILE exists, overwrite(s/n)? " \
    && [ x"$REPLY" != xs ] \
    && exit \
    || rm -f $OFILE

let START=0
let STEP=16384
let SIZE="$(stat -c %s $IFILE)"
let NSTEPS=SIZE/STEP+1

echo -n "Converting..."
for ((n=0 ; n<$NSTEPS ; n++)) ; do
    echo -ne "\r$START bytes converted..."
    #-- ibs input block size, skip N blocks, copy count blocks
    x="$(dd if=$IFILE ibs=$STEP skip=$n count=1 2>/dev/null)"
    echo -ne "$x" >> $OFILE
    let START+=STEP
done 
echo -e "\rConversion complete ($SIZE bytes)." 

#-- end --#

unescape.shとして保存しchmod u+x unescape.shて呼び出してみましょう。

./unescape filename.txt outresult.txt

ファイルに NULL 文字がある場合は警告が表示され、NULL は無視されます。

おすすめ記事