awk 작업을 실행하기 전에 입력을 필터링하는 것이 좋은 생각입니까?

awk 작업을 실행하기 전에 입력을 필터링하는 것이 좋은 생각입니까?

입력이 있는 경우 awk작업을 실행하기 전에 데이터를 필터링하는 것이 더 낫습니까, 아니면 에서 모든 필터링을 수행해야 합니까 awk?

예를 들어 다음 입력이 주어지면:

$ echo "foo\nbar\nbaz"
foo
bar
baz

다음을 실행해야 할까요?

$ echo "foo\nbar\nbaz" | sed 1q | awk '{ print $0 " cats" }'
foo cats

또는:

$ echo "foo\nbar\nbaz" | awk 'NR == 1 { print $0 " cats" }'
foo cats
  • 왜 둘 중 하나를 실행해야 합니까?
  • 다른 도구를 사용해야 합니까?
  • 어떤 요소를 고려해야 합니까?
  • 이러한 요소를 어떻게 테스트할 수 있나요?

답변1

이 특정한 경우에는 두 번째 옵션이 더 좋습니다.

일반적으로 파이프라인의 유틸리티 수를 최소화하는 것이 더 효율적입니다. 불필요한 프로세스를 포크(시작)하지 않는 것이 가장 좋습니다(불필요한 sed프로세스를 사용한 첫 번째 예에서처럼). 인터넷에서는 민원사례를 찾기가 어렵지 않다.고양이의 쓸모없는 용도.

대부분의 최신 Unix 계열 시스템 * 에서 분기는 매우 효율적으로 수행되지만 시작되는 프로세스의 크기에 따라 다릅니다(예: 시작 perl또는 실행은 또는 python보다 훨씬 느립니다 ) .sedawk

일회성 명령의 경우 이는 그다지 중요하지 않습니다. 그러나 파이프라인이 루프 내에 있고 여러 번 실행되는 경우 파이프라인에서 불필요한 프로세스를 제거하면 총 실행 시간이 크게 단축될 수 있습니다.

구체적인 질문

왜 둘 중 하나를 실행해야 합니까?

둘 중 하나의 구문에 더 익숙하다면 가장 익숙한 도구/언어를 사용하는 것이 코드 가독성(및 유지 관리성)에 더 나을 수 있습니다.

다른 도구를 사용해야 합니까?

이 특정한 경우에는 그렇게 생각하지 않습니다. awk및 둘 다 sed이러한 종류의 작업에 적합한 도구입니다.

어떤 요소를 고려해야 합니까?

여러 파일을 처리해야 하는 경우(예: 루프에서) 속도/효율성이 중요합니다.

하나의 큰 파일을 처리하는 경우에는 코드 가독성이 더 중요할 수 있습니다.

이러한 요소를 어떻게 테스트할 수 있나요?

timeBash에 내장된 쉘로 사용할 수 있을 뿐만 아니라 독립 실행형 실행 프로그램으로도 사용할 수 있는 유틸리티를 사용하여 다양한 버전을 프로파일링할 수 있습니다 . 예를 들어 두 개의 예제 명령을 실행하면 첫 번째 예제가 두 번째 예제보다 .012초 더 오래 걸렸음을 알 수 있습니다.

$ time echo "foo\nbar\nbaz" | sed 1q | awk '{ print $0 " cats" }'
foo\nbar\nbaz cats

real    0m0.056s
user    0m0.000s
sys     0m0.045s

$ time echo "foo\nbar\nbaz" | awk 'NR == 1 { print $0 " cats" }'
foo\nbar\nbaz cats

real    0m0.044s
user    0m0.000s
sys     0m0.031s

프로파일링 벤치마크는 시스템 로드 및 기타 제한 요소의 영향을 받으므로 어떤 버전이 다른 버전보다 빠른지 실제 그림을 얻으려면 이를 여러 번 반복해야 합니다.


* MS Windows에서는 포크~이다비용이 더 많이 들기 때문에 시작되는 프로세스 수를 최소화하면 Cygwin과 같은 환경에서 실행할 때 차이가 발생합니다.

답변2

사용해도 충분해요(또는sed) 이러한 간단한 경우를 위한 도구입니다. 여러 도구를 조합하면 너무 복잡해지고 중복되는 경우가 많습니다.

echo -e "foo\nbar\nbaz" | awk 'NR==1{print $0" cats"}'

출력:

foo cats

어떤 요소를 고려해야 합니까?

필요한 텍스트 처리에는 여러 가지 도구의 조합이 필요한지 확인하십시오. 그렇지 않으면 하나의 도구를 사용하십시오.

입력 문자열의 첫 번째 단어 앞에 특정 단어만 추가하면 된다고 가정해 보겠습니다.sed도구:

echo -e "foo\nbar\nbaz" | sed 's/^.*$/& cats/; 1q'
foo cats

echo -e, e플래그는 "백슬래시 이스케이프 해석을 활성화합니다"


어쨌든 입력 텍스트가 얼마나 복잡한지, 텍스트 처리 규칙이 얼마나 정교한지에 따라 다릅니다.

관련 정보