나는 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는 read
NUL 문자를 처리할 수 없습니다. 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
그러면 \375
6바이트 UTF-8 문자가 도입됩니다. 단, 위의 6번째 ( A
)는 UTF-8 문자에는 유효하지 않습니다. 여전히 \375\200\200\200\200A
in 로 끝나며 $a
이는 bash
6으로 계산됩니다.수치처음 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
키스아니요?