나는 파일의 각 줄의 처음 3자를 (cut을 사용하여 가져옴) 배열의 문자열과 비교하는 스크립트를 작성하고 있습니다. 주위를 둘러보았지만 찾은 솔루션이 내 시스템에서 작동하지 않습니다.
이제 다음과 같이 보입니다.
weekdays=([Mon]=1 [Tue]=1 [Wed]=1 [Thu]=1 [Fri]=1 [Sat]=1 [Sun]=1)
input="/Foo/Bar.log"
while read -r line
do
cutline="$(echo ${line} | cut -c 1-3"
if [[ ${weekdays["$cutline"]} ]]
then
echo "Match"
else
echo "No Match"
fi
done < ${input}
줄은 올바르게 잘렸지만 처음 3개의 글자가 무엇이든 "일치"를 반환하기 때문에 테스트 중에 무언가가 거짓 긍정을 반환합니다.
-x를 사용하여 스크립트를 검사하면 실제 테스트 대신 사용되는 것으로 표시됩니다.
[[ -n 1 ]]
표현으로 테스트 [ ]
하면1
전체 단어 대신 배열의 모든 문자를 확인합니까, 아니면 다른 문제가 있습니까?
괜찮다면 다음 문자로 이동하기 전에 줄의 처음 3글자와 배열의 모든 문자를 비교할 수 있는 다른 방법이 있습니까?
참고: 저는 실제로 Bash 4를 실행하고 있으므로 연관 배열이 작동해야 합니다.
답변1
기본적인 오류는 실제로 연관 배열을 선언하지 않는다는 것입니다.
$ weekdays=(["Mon"]=1 ["Tue"]=1 ["Wed"]=1 ["Thu"]=1 ["Fri"]=1 ["Sat"]=1 ["Sun"]=1)
$ echo ${weekdays[@]}
1
$ echo ${weekdays[0]}
1
$ echo ${weekdays[2]}
$
bash가 이를 어떻게 처리하는지, 왜 one 만 취하는지 완전히 확신할 수는 없지만 1
연관 배열은 아니라고 확신합니다. man bash
(강조)에 설명된 대로 :
name[subscript]=value 구문을 사용하여 변수를 할당하면 인덱스 배열이 자동으로 생성됩니다. 아래 첨자는 숫자로 평가되어야 하는 산술 표현식으로 처리됩니다. 인덱싱된 배열을 명시적으로 선언하려면 discover -a name을 사용하십시오(아래 SHELL BUILTIN 명령 참조). -a name[subscript] 문도 허용됩니다.
연관 배열은 -A name 명령문을 사용하여 생성됩니다.
따라서 이것을 시도해 보십시오. 예상대로 작동할 것입니다.
declare -A weekdays=(["Mon"]=1 ["Tue"]=1 ["Wed"]=1 ["Thu"]=1 ["Fri"]=1 ["Sat"]=1 ["Sun"]=1)
즉, 스크립트는 필요한 것보다 조금 더 복잡합니다. 동일한 방법을 사용하는 더 간단한 버전은 다음과 같습니다.
#!/bin/bash
declare -A weekdays=(["Mon"]=1 ["Tue"]=1 ["Wed"]=1 ["Thu"]=1 ["Fri"]=1 ["Sat"]=1 ["Sun"]=1)
input="/Foo/Bar.log"
cut -c 1-3 "$input" | while read -r line; do
if [[ ${weekdays["$line"]} ]]
then
echo "Match : $cutline : ${weekdays[$line]}"
else
echo "No Match"
fi
done
내가 이렇게 할 수도 있지만:
#!/bin/bash
cut -c 1-3 "$1" | while read -r line; do
case $line in
"Mon"|"Tue"|"Wed"|"Thu"|"Fri"|"Sat"|"Sun")
echo yes;;
*)
echo no;;
esac
done
그런 다음 대상 파일 이름을 인수로 사용하여 스크립트를 실행합니다.
script.sh /Foo/Bar.log"
답변2
텍스트 처리 도구를 호출하여 텍스트를 처리하겠습니다., 모든 입력 줄에 여러 도구가 있는 것은 아닙니다.
awk -v 'weekday=(Mon|Tue|Wed|Thu|Fri|Sat|Sun)' '
{print ($0 ~ "^" weekday ? "" : "No ") "Match"}' < "$input"
각 입력 줄에 대해 특정 응용 프로그램을 실행해야 하는 경우 루프를 사용할 수 있지만 단순히 텍스트 처리(예: 일부 파일에 줄을 출력하는 등)인 경우 awk
다음을 수행할 수 있습니다.
awk -v 'weekday=Mon|Tue|Wed|Thu|Fri|Sat|Sun' '
(day = substr($0, 1, 3)) ~ weekday {
print substr($0, 4) > day ".txt"
} < "$input"