빈 줄을 화장실로 파이프할 수 있는 경우 더 나은 쉘 솔루션

빈 줄을 화장실로 파이프할 수 있는 경우 더 나은 쉘 솔루션

다음과 같은 작업을 수행하는 코드가 있습니다.

#!/bin/sh
CONTENTS=$(cat "somefile")
RELEVANT_LINES=$(echo "$CONTENTS" | grep -E "SEARCHEXPR")
COUNT=$(echo "$RELEVANT_LINES" | wc -l)

나를 짜증나게 하는 것은 이 코드가 세 번째 줄을 다음으로 대체하여 제공된 올바른 출력과 비교하여 일치하는 항목 없이 동일한 출력을 출력하지 않는다는 것입니다.

COUNT=$(echo "$CONTENTS" | grep -E "SEARCHEXPR" | wc -l)

결국 일치하는 항목이 없을 때 RELEVANT_LINES가 빈 문자열로 설정되고 echo는 줄 수가 1인 빈 문자열 + \n 줄을 출력한다는 사실을 추적했습니다.

세 번째 줄에서 printf 및 echo -n을 사용해 보았지만 우아한 해결 방법을 찾을 수 없었고 COUNT=$(echo "$RELEVANT_LINES" | grep '0' | wc -l)전체 소스 파일을 정규식으로 두 번 필터링하지 않아도 되도록 (0을 포함하는 모든 줄)을 사용하게 되었습니다.

이것은 정확할 수 없지만 올바른 해결책을 찾을 수 없습니다.

나는 그것이 그렇게 강력할 것이라고 확신하지 못하기 때문에 스크립트 작성을 포기하지 않았 으며, 순전히 깔끔함을 -eq ''위해 파이프를 직접 사용하는 것을 선호합니다 .wc

grep을 통해 필터링한 후 0줄과 1줄을 깔끔하게 구별할 수 있도록 변수에서 파일 내용을 가져오는 방법에 대한 팁이 있습니까? :)

답변1

CONTENTS다시 사용하여 파일을 저장하는 것은 약간 중복됩니다 echo.

lines=$(cat "somefile" | grep -E "SEARCHEXPR")

더 구체적으로

lines=$(grep -E "SEARCHEXPR" "somefile")

일치하는 행 수만 원하면 다음을 사용하십시오.grep -c

count=$(grep -c -E "SEARCHEXPR" "somefile")

당신이 보고 있는 즉각적인 문제는 echo줄 바꿈이 항상 출력된다는 사실로 인해 발생합니다. 명령 대체에서 최소한 한 줄을 얻으면 실제로 도움이 됩니다. 왜냐하면 명령 대체 때문입니다.후행 줄 바꿈 제거. 또한 후행 빈 줄에서도 작동합니다. 이것을 시도하고 다음을 참조하십시오 x=$(echo foo; echo; echo); echo "$x".

계산 이외의 다른 방법으로 쉘 스크립트의 행을 처리하려는 경우 텍스트를 변수에 저장하는 것이 최선의 선택이 아닐 수 있습니다. 당신은 시도 할 수 있습니다

for line in $lines ; do 
    something with "$line"
done

그러나 이는 인용되지 않은 변수, 즉 파일 이름 글로빙 및 공백의 토큰화와 같은 일반적인 문제로 인해 어려움을 겪습니다. "foo bar doo"가 포함된 줄은 기본적으로 공백도 구분되므로 세 줄로 처리됩니다.

루프를 사용하고 싶을 수도 있지만 while read이 경우 프로세스 대체를 지원하는 쉘이 더 나을 수도 있습니다. 바라보다배쉬 FAQ 001그리고find & while 이후에 변수가 변경되지 않았습니다.그리고Bash에서 파이프가 값을 설정하지 않은 후에 읽습니다..

관련 정보