![파일 이름의 각 문자를 반복하는 방법은 무엇입니까?](https://linux55.com/image/192571/%ED%8C%8C%EC%9D%BC%20%EC%9D%B4%EB%A6%84%EC%9D%98%20%EA%B0%81%20%EB%AC%B8%EC%9E%90%EB%A5%BC%20%EB%B0%98%EB%B3%B5%ED%95%98%EB%8A%94%20%EB%B0%A9%EB%B2%95%EC%9D%80%20%EB%AC%B4%EC%97%87%EC%9E%85%EB%8B%88%EA%B9%8C%3F.png)
for
그래서 외부 루프는 디렉토리의 모든 파일을 반복하고 내부 for
루프는 해당 파일 이름의 모든 문자를 반복하는 간단한 중첩 루프가 있습니다 .
#!/bin/bash
if [ $# -lt 1 ]
then
echo "Please provide an argument"
exit
fi
for file in `ls $1`
do
for ch in $file
do
echo $ch
done
done
위 스크립트는 작동하지 않습니다. 내부 루프는 파일 이름의 모든 문자를 반복하지 않고 전체 내용을 반복합니다.
고쳐 쓰다:
@ilkkachu의 답변을 바탕으로 다음 스크립트를 생각해 낼 수 있었고 예상대로 작동합니다. 하지만 for...in
루프를 사용하지 않고 문자열을 반복 할 수 있는지 궁금합니다 .
#!/bin/bash
if [ $# -lt 1 ]
then
echo "Please provide an argument"
exit
fi
for file in `ls $1`; do
for ((i=0; i<${#file}; i++)); do
printf "%q\n" "${file:i:1}"
done
done
답변1
Bash를 사용하고 있으므로:
#!/bin/bash
word=foobar
for ((i=0; i < ${#word}; i++)); do
printf "char: %q\n" "${word:i:1}"
done
${var:p:k}
주어진케이var
위치에서 시작하는 문자피, ${#var}
는 내용의 길이입니다 var
. printf %q
명시적인 형식으로 출력을 인쇄합니다 $'\n'
. 예를 들어 개행 문자는 .
답변2
문자열이 수백자를 초과하는 경우(예, 파일 이름의 경우 가능성 없음) 문자열 길이에 대해 for 루프를 사용하고 인덱스에서 문자를 추출하는 속도가 i
매우 느려집니다.
이 답변은 고급 bash 기술을 사용합니다.
while IFS= read -r -d "" -n 1 char; do
# do something with char, like adding it to an array
chars+=( "$char" )
done < <(printf '%s' "$string")
# inspect the array
declare -p chars
이것은프로세스 교체문자열을 읽는 동안 루프로 리디렉션합니다. 나는 printf
문자열 끝에 개행 문자를 추가하는 것을 피하는 데 사용합니다. 프로세스 대체를 사용하는 주요 이점 printf ... | while read ...
은 루프가 발생한다는 것입니다.현재의쉘이 아니라아들껍데기.
나는 느림의 정도에 대해 궁금해하곤 했습니다.벤치마킹.
답변3
완전성을 위해 질문에 태그가 지정되어 있어도세게 때리다, POSIX 셸 기능만 사용하는 대안:
#!/bin/sh
for fname
do
while [ "${#fname}" -ge 1 ]
do
rest=${fname#?} char=${fname%"$rest"} fname=$rest
printf '%s\n' "$char" # Do something with the current character
done
done
내부 루프의 역할:
첫 번째 문자를 뺀 값으로 설정합니다
rest
.fname
rest
삭제된 단일 문자를 에 할당fname
합니다char
.fname
의 값으로 설정rest
하고 모든 문자가 처리될 때까지 반복합니다.
확장이 패턴으로 사용되는 것을 ${fname%"$rest"}
방지하기 위해 따옴표를 사용하십시오 .$rest
그런데, for file in `ls $1`
피해야 합니다. 가장 확실한 이유는 파일 이름에 IFS
.배쉬 트랩 1, 해야 할 일을 포함합니다.
답변4
bash
문자열 분할 연산자를 사용합니다 .
s="string"
for c in $(seq 0 $((${#s}-1))); do echo "${s:c:1}"; done
s
t
r
i
n
g
귀하에게 적용되는 스크립트는 다음과 같습니다.
#!/bin/bash
for f in *; do
echo "Char in $f:"
for i in $(seq 0 $((${#f}-1))); do
echo "${f:i:1}"
done
done