파일의 여러 열에 있는 값을 검색하고 일치시키려면 awk 명령을 어떻게 수정합니까?

파일의 여러 열에 있는 값을 검색하고 일치시키려면 awk 명령을 어떻게 수정합니까?

다음 스크립트가 저장되어 bin있으며 정의된 변수를 기반으로 출력을 얻는 데 사용됩니다. 현재 스크립트는 열 1에 대해 실행 중이며 출력을 제공합니다. 열 1 또는 열 2와 일치할 때 출력을 제공하도록 이 스크립트를 어떻게 업데이트할 수 있습니까?

cat ~/bin/POUT

#!/bin/bash

exec awk -v arg=${1:?} '$1==arg' "${@:2}" inputfile

입력 파일 -:

 DEV       RETAIL          RETAILDEVNode  
TEST      RETAILTEST       RETAILTESTNode 
TEST       AUDIT            AUDITTESTNode
QA         AUDITQA         AUDITQANode
PROD       SALE            SALEPRODNode
QA         SALEQA           SALETESTNode
QA        FINANCE         FINANCEQANode
PROD      FINANCE         FINANCEPRODNode

현재 예상되는 결과를 얻고 있습니다 -

$ POUT QA
QA         AUDITQA         AUDITQANode
QA         SALEQA           SALETESTNode
QA        FINANCE         FINANCEQANode

또한 다음과 같은 출력을 원합니다(열 2에서도 검색).

$ POUT AUDITQA
QA         AUDITQA         AUDITQANode

Want output like this also (put any matching value and search in column 2 aslo) ---

$ POUT DITQ 
QA         AUDITQA         AUDITQANode

따라서 변수에 입력이 무엇이든 열 1과 열 2를 검색하여 출력을 제공해야 합니다.

답변1

#!/bin/bash
arg="${1:?}"    # Capture argument value or fail
shift

awk -v arg="${arg//\\/\\\\}" 'index($1, arg) || index($2, arg)' "$@" inputfile

쉘 변수를 사용할 때는 항상 큰따옴표를 사용하십시오. (가끔 예외가 발생하는 이유를 이해할 때까지 이는 사실입니다. 그때까지는 항상 큰따옴표를 사용하십시오.)

$arg쉘 변수는 백슬래시 처리 취소를 위해 awk무작위로 변수를 변수에 할당합니다 .argawk

나머지 명령줄 인수를 전달하는 이유를 이해할 수 없습니다.awk 그리고inputfile지속적인 소스로 제공됩니다. 그래도 의도한 경우를 대비해 보관했습니다.

답변2

가능한:

#! /bin/sh -
export ARG="${1?}"
shift
exec awk '
  BEGIN{
    field = 1
    arg = ENVIRON["ARG"] ""
  }
  $field == arg' "$@" inputfile

그런 다음 이를 호출하여 CLI 이전 버전과의 호환성을 유지하면서 두 번째 필드를 POUT AUDITQA field=2살펴볼 수 있습니다.AUDITQA

몇 가지 참고사항:

  • bash 또는 sh에서 따옴표를 확장하는 것을 잊어버린 경우, -v arg=${1?}이는 Split+glob의 영향을 받습니다. 이는 임의의 명령 실행 취약점을 야기하므로 매우 나쁩니다. 이것은 실제로 주어진 예 중 하나입니다.bash/POSIX 쉘에서 변수를 인용하는 것을 잊어버리는 보안 위험
  • -v임의의 텍스트를 전달하기 위해 맹글 백슬래시를 사용할 수 없습니다 -v. 따라서 ENVIRON위의 방법을 사용해도 아무런 문제가 없습니다 .
  • awk인수는 변수 할당으로 처리 되므로 foo=bar.txt파일 이름에 문자가 포함되어 있으면 . 대신 =로 전달해야 합니다 ../foo=bar.txtfoo=bar.txt
  • $fieldENVION["var"]/또는 -v숫자로 보이는 전달된 변수는 숫자 문자열로 처리되어 ==결국 문자열 비교 대신 숫자 비교를 수행하게 될 수 있습니다. 항상 문자열로 처리되도록 연결하므로 ""예 를 들어 인수를 사용하여 호출하면 10.0, 010 또는 1e1과 일치하지 않습니다.ENVIRON["ARG"]10

관련 정보