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 계열 시스템 * 에서는 분기가 매우 효율적으로 수행되지만 시작되는 프로세스의 크기에 따라 다릅니다. 예를 들어 perlOR 시작은 OR 보다 훨씬 느 python립니다 .sedawk

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

특정 문제

왜 이런 것을 실행하고 싶습니까?

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

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

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

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

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

대용량 파일을 자주 작업하는 경우 코드 가독성이 더 중요할 수 있습니다.

이러한 요소를 어떻게 테스트합니까?

time내장된 Bash 셸이나 독립 실행형 실행 프로그램으로 제공되는 이 유틸리티를 사용하여 다양한 버전을 분석 할 수 있습니다 . 예를 들어 두 개의 예제 명령을 실행하면 첫 번째 예제가 두 번째 예제보다 0.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플래그 "백슬래시 이스케이프 해석 활성화"


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

관련 정보