출력 파일의 내용을 grep하고 싶습니다. 예를 들어 ab
및 cd
.
파일은 다음과 같습니다.
asdf
ab
hgr
cd
ab
asdsda
지금 내가 다음과 같이 ab
하나씩 grep한다면cd
for i in $@
do
grep $i file
done
알겠어요
ab
ab
cd
내가 원하는 건
ab
cd
ab
우아한 해결책이 있습니까?
답변1
이 결과를 얻는 이유는 루프가 첫 번째 반복에서 발생하는 모든 사례를 먼저 실행 grep ab file
하고 반환 한 다음 이 루프가 첫 번째 반복 에서 발생하는 모든 사례를 실행 하고 반환하기 때문입니다 .ab
grep cd file
cd
file
for
루프가 필요하지 않습니다 .이 시도:
grep -e "^ab$" -e "^cd$" file
또는 -x
옵션을 사용하여 전체 줄과 정확히 일치하는 일치 항목만 선택합니다( man grep
, thx ~선행은 이루기가 어렵다):
grep -x -e "ab" -e "cd" file
출력은 다음과 같습니다:
ab
cd
ab
또는(GNU grep
또는 호환이 \|
표준 BRE 연산자가 아니라고 가정):
grep "^\(ab\|cd\)$" file
GNU와 동일 sed
:
sed '/^\(ab\|cd\)$/!d' file
답변2
사용:
IFS='
' # to join "$*" with newline
grep -e "$*" < file
grep -- "$patterns"
또는 에서 grep -e "$patterns"
의 각 행은 $patterns
찾을 패턴입니다(ORed). ( 패턴 자체가 여러 줄인 경우 "$@"
이 점을 염두에 두는 것이 좋습니다 .)
POSIX 쉘에서는 "$*"
위치 인수와 $IFS
.
-x
패턴이 줄 내의 하위 문자열이 아닌 줄과 정확히 일치하도록 하려면 x
이 옵션을 추가하세요 .
ab
cd
및 (그래서 none ) 과 일치하는 행은 -x
한 번만 인쇄되며 이는 다중 패스 접근 방식과의 또 다른 차이점입니다. 일치하는 각 패턴에 대해 한 번 인쇄하려면 다음을 사용할 수 있습니다 awk
.
awk '
BEGIN {
for (i = 1; i < ARGC; i++) pattern[ARGV[i]]
ARGC = 1
}
{for (p in pattern) if ($0 ~ p) print}' "$@" < file
그러나 awk
패턴은 확장된 정규식(예: grep -E
)이라는 점에 유의하세요.기초적인grep
없이 이해되는 정규식 -E
(예를 들어 와 x+
일치 하지만 하나 이상의 es와 일치함 )x+
grep
x
awk