상태 정보와 기타 다양한 텍스트로 채워진 txt 파일의 특정 부분을 삭제하는 스크립트를 만들려고 합니다. 주요 if 문을 끝낼 수 없습니다. 추가적으로, output.txt를 생성하는 스크립트에 date 명령을 넣어서 가장 오래된 상태 정보를 제거하려고 했습니다. 가장 오래된 정보를 삭제하게 하는 방법이 있나요? 나는 주로 if 문이 끝나기를 원합니다. 감사해요. (또한 원래 else if 를 elif 로 사용했지만 결과는 동일했습니다.)
./count.sh: 30행: else' ./count.sh: line 30:
예상치 못한 표시 근처에서 구문 오류가 발생했습니다.
WCOUNT=$(wc -l output.txt $1 | awk '{print $1}')
if [[ $WCOUNT -gt 50 ]]; then
if [[ "grep CLIENTSTART output.txt" != null ]]; then
echo $WCOUNT
sed -i '/\*\*\*CLIENTSTART/,/CLIENTEND\*\*\*/ d' output.txt
echo $WCOUNT
else if [[ -n "grep DHCPSTART output.txt" ]]; then
echo $WCOUNT
sed -i '/\*\*\*DHCPSTART/,/DHCPEND\*\*\*/ d' output.txt
echo $WCOUNT
else if [[ -n "grep DNSSTART output.txt" ]]; then
echo $WCOUNT
sed -i '/\*\*\*DNSSTART/,/DNSEND\*\*\*/ d' output.txt
echo $WCOUNT
else if [[ -n "grep WEBSTART output.txt" ]]; then
echo $WCOUNT
sed -i '/\*\*\*WEBSTART/,/WEBEND\*\*\*/ d' output.txt
echo $WCOUNT
else
echo "Cannot help you"
fi
else
echo "You're good, homie. It's under 500"
fi
답변1
여기서 문제는 else if
대신 을 사용하면 elif
프로그램에 중첩이 추가되고 fi
추가 조건문을 종료하기 위해 더 많은 문을 추가해야 한다는 것입니다.
다음은 내가 의미하는 바를 보여주기 위해 약간 다른 들여쓰기가 포함된 프로그램의 편집된 버전입니다.
WCOUNT=$(wc -l output.txt $1 | awk '{print $1}')
if [[ $WCOUNT -gt 50 ]]; then
if [[ "grep CLIENTSTART output.txt" != null ]]; then
echo $WCOUNT
sed -i '/\*\*\*CLIENTSTART/,/CLIENTEND\*\*\*/ d' output.txt
echo $WCOUNT
else
if [[ -n "grep DHCPSTART output.txt" ]]; then
echo $WCOUNT
sed -i '/\*\*\*DHCPSTART/,/DHCPEND\*\*\*/ d' output.txt
echo $WCOUNT
else
if [[ -n "grep DNSSTART output.txt" ]]; then
echo $WCOUNT
sed -i '/\*\*\*DNSSTART/,/DNSEND\*\*\*/ d' output.txt
echo $WCOUNT
else
if [[ -n "grep WEBSTART output.txt" ]]; then
echo $WCOUNT
sed -i '/\*\*\*WEBSTART/,/WEBEND\*\*\*/ d' output.txt
echo $WCOUNT
else
echo "Cannot help you"
fi
fi
fi
fi
else
echo "You're good, homie. It's under 500"
fi
또는 다음을 사용할 수 있습니다.elif
WCOUNT=$(wc -l output.txt $1 | awk '{print $1}')
if [[ $WCOUNT -gt 50 ]]; then
if [[ "grep CLIENTSTART output.txt" != null ]]; then
echo $WCOUNT
sed -i '/\*\*\*CLIENTSTART/,/CLIENTEND\*\*\*/ d' output.txt
echo $WCOUNT
elif [[ -n "grep DHCPSTART output.txt" ]]; then
echo $WCOUNT
sed -i '/\*\*\*DHCPSTART/,/DHCPEND\*\*\*/ d' output.txt
echo $WCOUNT
elif [[ -n "grep DNSSTART output.txt" ]]; then
echo $WCOUNT
sed -i '/\*\*\*DNSSTART/,/DNSEND\*\*\*/ d' output.txt
echo $WCOUNT
elif [[ -n "grep WEBSTART output.txt" ]]; then
echo $WCOUNT
sed -i '/\*\*\*WEBSTART/,/WEBEND\*\*\*/ d' output.txt
echo $WCOUNT
else
echo "Cannot help you"
fi
else
echo "You're good, homie. It's under 500"
fi
(또한 약간 까다롭게 말하면 50개 이상의 행이 있는지 확인하고 있지만 출력 메시지에는 500개 행을 확인한다고 나와 있습니다. 기술적으로는 500개 미만의 행이 있지만 이는 약간 오해의 소지가 있습니다. p)
편집: 다른 사람들이 지적했듯이 이렇게 하면 구문 오류가 해결되지만 스크립트에는 여전히 다른 문제가 있습니다. 나는 또한 그들의 의견/답변을 읽는 것이 좋습니다.
답변2
구문 오류가 발생하는 이유는 명령문 else if
이 elif
.
두 개의 파일이 제공되면 wc -l
세 줄의 출력이 생성됩니다.
$ wc -l .profile .profile
30 .profile
30 .profile
60 total
이는 따옴표가 없는 첫 번째 if
test에 영향을 미치며 $WCOUNT
확장 시 또 다른 구문 오류가 발생합니다.
당신은 원할 수도 있습니다
WCOUNT=$( wc -l <output.txt )
또한 문자열에 대한 여러 가지 테스트가 있습니다 "grep DHCPSTART output.txt"
.언제나그건 진실이야.
파일에 문자열이 있는지 테스트하려면 다음을 사용하십시오.
if grep -Fq 'fixed string' filename; then
예를 들어
if grep -Fq 'CLIENTSTART' output.txt; then
# do something
elif grep -Fq 'DHCPSTART' output.txt; then
# do something
else
# do something
fi
실제 출력 생성을 중지합니다 -q
. grep
종료 상태는 문자열이 발견되었는지 알려주며, 이것이 if
이 명령문을 작동하게 만듭니다(플래그는 또한 grep
첫 번째 일치에서 파일 읽기가 중지되도록 합니다). 이 -F
플래그를 사용하면 grep
지정된 패턴이 정규 표현식이 아닌 고정 문자열로 처리됩니다.
스크립트 내부 구조에 대한 제안:
tmpfile=$(mktemp)
for string in CLIENT DHCP DNS WEB; do
if grep -Fq "${string}START" output.txt; then
sed "/\*\*\*${string}START/,/${string}END\*\*\*/d" \
output.txt >"$tmpfile"
break
fi
done
if [ -s "$tmpfile" ]; then
mv "$tmpfile" output.txt
else
echo 'Can not help you'
rm -f "$tmpfile"
fi
[ -s "$tmpfile" ]
파일 $tmpfile
크기가 0보다 크면( 호출 시의 크기) sed
테스트가 성공합니다 .
for
break
논리 를 모방 if ... then ... elif
하지만 보다 간결한 방식으로 루프를 사용합니다.