bash read를 사용하여 문자 단위로 읽기

bash read를 사용하여 문자 단위로 읽기

나는 bash를 사용하여 문자별로 파일을 읽으려고 노력해 왔습니다.

많은 시행착오 끝에 나는 이것이 효과가 있다는 것을 알았습니다.

exec 4<file.txt 
declare -i n
while read -r ch <&4; 
     n=0
     while [ ! $n -eq ${#ch} ]
           do  echo -n "${ch:$n:1}"
               (( n++ ))
          done
     echo "" 
     done

즉, 한 줄씩 읽을 수 있고 각 줄을 문자별로 반복할 수 있습니다.

이 작업을 수행하기 전에 다음을 시도했습니다. exec 4<file.txt && while read -r -n1 ch <&4; do; echo -n "$ch"; done 하지만 그럴 것입니다.파일의 모든 공백 건너뛰기.

이유를 설명해 주실 수 있나요? 두 번째 전략(즉, bash 읽기를 사용하여 문자별로 읽기)을 작동시킬 수 있는 방법이 있습니까?

답변1

선행 및 후행 문자 건너뛰기를 중지 $IFS하려면 인수에서 공백 문자를 제거 해야 합니다 (사용할 경우 공백 문자(있는 경우)가 선행 및 후행 문자가 되므로 건너뜁니다).read-n1

while IFS= read -rn1 a; do printf %s "$a"; done

하지만 그런 경우에도 bash는 read개행을 건너뛰므로 다음을 사용하여 문제를 해결할 수 있습니다.

while IFS= read -rn1 a; do printf %s "${a:-$'\n'}"; done

IFS= read -d '' -rn1이것은 하나의 문자를 읽는 명령이지만, 대체 명령이나 더 나은 명령 IFS= read -N1(4.1에 추가, 복사 ksh93( o추가)) 을 사용할 수도 있습니다 .

Bash는 readNUL 문자를 처리할 수 없습니다. ksh93에도 bash와 동일한 문제가 있습니다.

zsh 사용:

while read -ku0 a; do print -rn -- "$a"; done

(zsh는 NUL 문자를 처리할 수 있습니다).

read -k/n/N좀 읽어보신 분들 참고하세요수치, 아니요바이트. 따라서 다중 바이트 문자의 경우 전체 문자를 읽을 때까지 여러 바이트를 읽어야 할 수도 있습니다. 입력에 유효하지 않은 문자가 포함되어 있으면 유효한 문자를 형성하지 않는 바이트 시퀀스가 ​​포함된 변수가 생성될 수 있으며 쉘은 이를 여러 개의 문자로 계산하게 될 수 있습니다.수치. 예를 들어 UTF-8 로케일에서는 다음과 같습니다.

$ printf '\375\200\200\200\200ABC' | bash -c '
    IFS= read  -rN1 a; echo "${#a}"'
6

그러면 \3756바이트 UTF-8 문자가 도입됩니다. 단, 위의 6번째 ( A)는 UTF-8 문자에는 유효하지 않습니다. 여전히 \375\200\200\200\200Ain 로 끝나며 $a이는 bash6으로 계산됩니다.수치처음 5개는 실제 문자는 아니지만 5바이트에 불과하며 문자의 일부를 구성하지 않습니다.

답변2

cut다음은 for,loop&를 사용한 간단한 예 입니다 wc.

bytes=$(wc -c < /etc/passwd)
file=$(</etc/passwd)

for ((i=0; i<bytes; i++)); do
    echo $file | cut -c $i
done

키스아니요?

관련 정보