순수 bash를 사용하여 파일의 문자열을 일치시키는 방법은 무엇입니까?

순수 bash를 사용하여 파일의 문자열을 일치시키는 방법은 무엇입니까?

그래서 파일의 문자열/또는 단어를 일치시키고 싶지만아니요외부 도구( grepsed)를 사용하세요. 순수한 bash만 사용하세요.

본질적으로 나는 다음과 같은 것을 원합니다.

grep "string" file

또는

grep -w "string" file

순수한 bash에서.

추신: 나는 파일에서 정확한 문자열을 일치시키는 데만 관심이 있으므로(개행 유무에 관계없이) 완전한 정규식 지원은 필요하지 않습니다(다른 외부 도구가 이를 지원할 수 있음).

답변1

할 수 있어요. 그러나 이것은 아주 아주 나쁜 생각입니다. grep특정 셸(Bash)의 기능에 의존하기 때문에 다음보다 훨씬 느릴 것입니다(수십 배 더 느림) .

그러면 다음과 유사하게 첫 번째 인수로 제공된 정규식 패턴과 일치하는 행이 인쇄됩니다 grep pattern.

#!/bin/bash -

regexp="$1"
ret=1
while IFS= read -r line || [ -n "$line" ]; do
  if [[ $line =~ $regexp ]]; then
    printf '%s\n' "$line"
    ret=0
  fi
done
exit "$ret"

다른 이름으로 저장 foo.bash하고 다음과 같이 실행하세요.

foo.bash pattern < inputFile

또는 표준 sh구문을 사용하여 정규식 대신 고정 문자열을 찾습니다.

#!/bin/sh -

string="$1"
ret=1
while IFS= read -r line || [ -n "$line" ]; do
  case $line in
    (*"$string"*)
      printf '%s\n' "$string"
      ret=0
  esac
done
exit "$ret"

( 와 같은 것을 얻으려면 printf로 바꾸십시오 .)exit 0grep -q

얼마나 느린지 알려드리기 위해 10001줄만 있는 파일을 만들었습니다. 처음 5000줄은 foo, 그다음에는 한 줄 bar, 또 다른 5000줄은 다음과 같습니다 foo.

perl -e 'print "foo\n" x 5000; print "bar\n"; print "foo\n" x 5000;' > file

grep이제 위 스크립트의 타이밍을 비교해 보세요.

$ time grep bar < file
bar

real    0m0.002s
user    0m0.002s
sys     0m0.000s

$ time ./foo.bash bar < file
bar

real    0m0.116s
user    0m0.101s
sys     0m0.016s

보시다시피 파일 크기가 작아도 차이가 눈에 띕니다. 보다 실질적인 스크립트를 사용하려고 하면 스크립트에 거의 견딜 수 없는 시간이 걸립니다.

$ perl -e 'print "foo\n" x 500000; print "bar\n"; print "foo\n" x 500000;' > file


$ time grep bar < file
bar

real    0m0.004s
user    0m0.000s
sys     0m0.004s


$ time ./foo.bash bar < file
bar

real    0m11.306s
user    0m10.117s
sys     0m1.188s

그러나 이는 부분적으로 Bash가 느리기 때문입니다. 표준 sh 버전은 Dash를 사용하여 더 빠르게 실행됩니다.

$ time dash foo2.sh bar < file
bar

real    0m3.467s
user    0m2.113s
sys     0m1.353s

그러나 여전히 격차가 있다.세 배의 규모.스크립트는 거의 순간적이지 않고 몇 초 정도 걸립니다 grep. 이 파일은 여전히 ​​100만 줄에 불과하며 크기는 약 4MB입니다. 문제를 볼 수 있기를 바랍니다.

관련 정보