특수 문자를 평가하지 않고 파일 내용을 인쇄하려면 어떻게 해야 합니까?

특수 문자를 평가하지 않고 파일 내용을 인쇄하려면 어떻게 해야 합니까?

이것은 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은 무시됩니다.

관련 정보