bash에 두 개의 변수가 있다고 가정 해보십시오.
MULTILINE="I have
more than one line"
SINGLE_LINE="I only have one line
"
변수에 실제로 두 줄 이상의 텍스트가 포함되어 있는지 확인하고 추가 줄 바꿈 문자를 무시합니다.
그래서 이건:
if [ some test on "$MULTILINE" ]; then echo 'yes'; else echo 'no'; fi
인쇄 yes
하고 이것을 :
if [ some test on "$SINGLE_LINE" ]; then echo 'yes'; else echo 'no'; fi
인쇄 no
합니다.
내 경우에는 빈 줄을 넣는 것에 대해 걱정할 필요가 없지만 그렇게하는 방법을 아는 것은 아프지 않습니다.
어떻게해야합니까?
답변
내가 아는 가장 간단한 해결책은 다음과 같습니다.
if (( $(grep -c . <<<"$MULTILINE") > 1 ))
예 :
VAR="a
b"
if (( $(grep -c . <<<"$VAR") > 1 )); then
echo VAR has more than one line
else
echo VAR has at most one line
fi
==>
VAR has more than one line
위의 모든 빈 줄은 무시합니다. 선행, 후행 및 내부. 그러나 공백이 아닌 줄이 두 개 이상 있지 않으면 내부 공백 줄을 가질 수 없으므로 공백 줄이 트리밍 된 후 줄이 두 개 이상 있는지 여부를 변경할 수 없습니다.
답변
$ echo "$ MULTILINE"| 화장실 -l 2 $ echo "$ SINGLE_LINE"| 화장실 -l 2 $ echo "$ SINGLE_LINE"| sed -re '/ ^ $ / d'| 화장실 -l 1 $ echo "$ MULTILINE"| sed -re '/ ^ $ / d'| 화장실 -l 2
sed를 사용하여 공백과 빈 줄을 자르거나 삭제하는 방법에 대한 자세한 내용은 /programming/16414410/delete-empty-lines-using-sed
를 참조 하십시오 .
이제 인용 부호 안에 if expression ...
사용 $( ... )
하여 행 수를 얻고 숫자에 대해 테스트하십시오.
if [ "$ (echo"$ MULTILINE "| sed -re '/ ^ $ / d'| wc -l)"-gt 1]; 그때 '두 줄 이상'을 반향하십시오. 그밖에 '단일 또는 줄 없음'에코; fi
답변
이 코드 를 약간 수정하면 됩니다. 다음과 같이 재사용을 위해 자체 스크립트에 넣을 수 있습니다.
#!/bin/bash
nlhit=""
for (( i=0; i<${#1}; i++ )); do
if [[ "${1:$i:1}" == $'\n' ]]; then
nlhit="1"
elif [[ "$nlhit" == "1" ]]; then
exit 1
fi
done
exit 0
그런 다음 이전 스크립트의 이름을 가정하면 다음과 같이 사용할 수 있습니다 multiline-check.sh
.
#!/bin/bash
EMPTYLINE=""
BLANKLINE=" "
ONLYLINES="
"
MULTILINE="I have
more than one line"
SINGLE_LINE="I only have one line
"
SECOND_LINE="
I begin with a newline"
echo -n "EMPTYLINE Check: "
multiline-check.sh "$EMPTYLINE"
if [ $? -eq 1 ]; then echo "Yes"; else echo "No"; fi
echo -n "BLANKLINE Check: "
multiline-check.sh "$BLANKLINE"
if [ $? -eq 1 ]; then echo "Yes"; else echo "No"; fi
echo -n "ONLYLINES Check: "
multiline-check.sh "$ONLYLINES"
if [ $? -eq 1 ]; then echo "Yes"; else echo "No"; fi
echo -n "MULTILINE Check: "
multiline-check.sh "$MULTILINE"
if [ $? -eq 1 ]; then echo "Yes"; else echo "No"; fi
echo -n "SINGLE_LINE Check: "
multiline-check.sh "$SINGLE_LINE"
if [ $? -eq 1 ]; then echo "Yes"; else echo "No"; fi
echo -n "SECOND_LINE Check: "
multiline-check.sh "$SECOND_LINE"
if [ $? -eq 1 ]; then echo "Yes"; else echo "No"; fi
답변
후행 빈 줄 무시
다음을 사용하는 접근법이 있습니다 awk
.
echo "$TEST" | tac | awk 'f==0 && /./ {f=NR} END{if(f==NR){exit 0}; exit 1 }' && echo "Found A Single Line"
작동 방식 :
-
에코 “$ TEST”
이것은 우리가 관심있는 쉘 변수를 취하여 표준 출력으로 보냅니다.
-
tac
마지막 행이 먼저 리턴되도록 행 순서를 반대로합니다. 를 실행 한 후
tac
후행이 선행 행이됩니다.(이름
tac
은 역순으로 작동cat
하는 이유 와 반대입니다.)tac
cat
-
awk 'f==0 && /./ {f=NR} END{if(f==NR){exit 0}; exit 1 }'
이것은 비어 있지 않은 첫 번째 줄의 줄 번호를 변수에 저장
f
합니다. 모든 줄을 읽은 후f
총 줄 수와 비교 됩니다NR
. 경우f
IS가 동일NR
, 우리는`다음 코드로 종료, 단 한 줄 (초기 공백을 무시)와 첫 번째 빈 라인 후 하나 개 이상의 라인이 있다면 우리는 코드 0으로 종료했다. -
&& echo "Found A Single Line"
경우
awk
코드 0으로 종료 한 후echo
문이 실행됩니다.
선행 및 후행 빈 줄 모두 무시
하나의 추가 awk
변수 를 작성 하여 테스트를 확장하여 선행 및 후행 공백 행을 모두 무시할 수 있습니다.
echo "$TEST" | awk 'first==0 && /./ {first=NR} /./ {last=NR} END{if(first==last){exit 0}; exit 1 }' && echo " Found A Single Line"
이 버전의 awk
코드는 선행 및 후행 공백을 모두 처리하므로 tac
더 이상 필요하지 않습니다.
awk
코드를 한 번에 한 조각 씩 가져 오기 :
-
first==0 && /./ {first=NR}
변수
first
가 0 (또는 아직 설정되지 않은)이고 행에 문자가있는 문자이면first
행 번호 로 설정 하십시오. 때awk
라인을 읽는 완료,first
최초의 공백이 아닌 행의 행 번호로 설정됩니다. -
/./ {last=NR}
행에 문자가 있으면 변수
last
를 현재 행 번호 로 설정하십시오 .awk
모든 줄을 읽었을 때 ,이 변수는 마지막 비 공백 줄의 줄 번호를 갖습니다. -
END{if(first==last){exit 0}; exit 1 }
이것은 모든 줄을 읽은 후에 실행되었습니다. 경우
first
IS가 동일last
, 우리는 0 개 라인이 아닌 빈 라인과 본awk
코드로 종료0
. 그렇지 않으면 code로 종료됩니다1
. 쉘 스크립트는 보통if
문 또는&&
또는 로 종료 코드를 테스트 할 수 있습니다||
.