다음과 같은 두 개의 파일이 있다고 가정해 보겠습니다.
$ cat search_file.txt
This line contains kwd1.
This line contains kwd2.
This line contains no match.
This line contains no match.
This line contains kwd5.
$ cat search_kwd.sh
grep kwd1 search_file.txt
grep kwd2 search_file.txt
grep kwd3 search_file.txt
grep kwd4 search_file.txt
grep kwd5 search_file.txt
search_kwd.sh를 실행하면 다음과 같은 결과가 나타납니다.
$ sh search_kwd.sh
This line contains kwd1.
This line contains kwd2.
This line contains kwd5.
string
grep이 일치하는 항목을 찾지 못할 때마다 인쇄하고 싶습니다. 출력은 다음과 같습니다.
$ sh search_kwd.sh
This line contains kwd1.
This line contains kwd2.
string
string
This line contains kwd5.
Bash에서 어떻게 할 수 있나요?
답변1
grep
아무것도 발견되지 않으면 0이 아닌 코드로 종료합니다.
에서 man grep
:
일반적으로 종료 상태는 행이 선택된 경우 0, 행이 선택되지 않은 경우 1, 오류가 발생한 경우 2입니다.
따라서 다음을 사용할 수 있습니다.
grep kwd3 search_file.txt || echo "string"
답변2
@RoVo의 답변을 확장하려면 for 루프를 사용하여 모든 쿼리를 반복할 수 있습니다.
for term in "kwd1" "kwd2" "kwd3" "kwd4" "kwd5"; do
grep "$term" search_file.txt || echo "string"`
done
답변3
요청된 출력에는 각 입력 줄에 대해 한 줄의 출력이 있는 것 같으며 일치하면 해당 줄을 복사하고 그렇지 않으면 교체하면 됩니다. 파일을 5번 읽고 다음과 같이 인쇄하는 것보다 더 좋은 방법이 있습니까? per search_kwd.sh 파일은 입력 파일 대신 입력 파일에서 찾은 순서대로 행을 나열합니다.
대신 입력 파일을 한 번에 한 줄씩 처리해야 합니다. 이를 수행하는 데는 많은 도구가 있습니다. 예를 들어
#!/bin/sh
sed -e '/kwd1/{p;d}
/kwd2/{p;d}
/kwd3/{p;d}
/kwd4/{p;d}
/kwd5/{p;d}
s/.*/string/' search_file.txt
이는 일치하는 각 키워드에 대해 줄을 인쇄한 후 이를 버리고 다음 줄로 이동한다는 의미입니다. 모든 키워드를 살펴보고 일치하는 항목이 없으면 줄을 문자열로 변경합니다(그런 다음 암시적으로 인쇄합니다).
awk
이런 것을 사용할 수 있습니다
#!/bin/sh
awk '{ if (/kwd1|kwd2|kwd3|kwd4|kwd5/) { print } else {print "string" }}' search+file.txt
순수한 쉘 구현을 가질 수 있습니다
#!/bin/sh
while read -r line
do
case "$line" in
(*"kwd1"*|*"kwd2"*|*"kwd3"*|*"kwd4"*|*"kwd5"*) printf '%s\n' "$line" ;;
(*) printf '%s\n' "string" ;;
esac
done < search_file.txt
Perl, Ruby, Python을 사용할 수도 있습니다.