찾기, xarg, awk 문제

찾기, xarg, awk 문제

나는 명령을 가지고 있습니다 :

awk 'BEGIN{print "Name, Number"}/value/{print FILENAME, "," $8}' *.txt >> out.csv

디렉터리에서 txt 파일을 찾아보고, 값을 구문 분석하고, 헤더(이름, 번호)가 포함된 최종 csv 파일을 작성하는 데 완벽하게 작동합니다.

내 문제는 "너무 많다"는 것이므로 find 및 xarg를 사용하여 수정합니다.

find ./ -maxdepth 1 -type f -name '*.txt' | xargs awk 'BEGIN{print "Name, Number"}/value/{print FILENAME, "," $8}' | sed 's/\.\///g' >> out.csv

이것은 과거에는 효과가 있었지만 이제는 헤더가 최종 csv 파일에 여러 번 기록되는 경우가 있습니다. 이유는 모르겠습니다. 이는 디렉토리의 총 txt 파일 수와 관련이 있으므로 특정 수에 도달하면 이런 일이 발생하지만 확실하지 않습니다.

감사해요.

답변1

awk는 파일 배치 별로 find호출되므로 BEGIN필요한 모든 파일에 대해 한 번이 아니라 배치당 한 번 실행됩니다. ARGV[]모든 파일을 인수로 사용하여 awk를 호출하고 "인수가 너무 많습니다" 오류로 인해 쉘이 실패하는 대신 awk가 모든 파일을 입력으로 읽고 읽을 파일의 내부 배열을 채울 수 있습니다( ).

find ./ -maxdepth 1 -type f -name '*.txt' |
awk '
    BEGIN { OFS=","; print "Name", "Number" }
    NR==FNR { ARGV[ARGC++]=$0; next }
    /value/ { print substr(FILENAME,3), $8 }
' - > out.csv

또한 awk 스크립트에서 몇 가지 사항을 정리하고 sed에 대한 파이프를 제거했습니다. awk를 사용할 때는 sed가 필요하지 않기 때문입니다. 위의 명령을 호출할 때 출력 파일을 추가하는 대신 처음부터 새로 만들고 싶다고 가정했기 때문에 >>로 변경했습니다 .>

위의 내용은 파일 이름에 개행 문자가 포함되어 있지 않다고 가정합니다. 그렇다면 GNU 도구를 사용하여 -print0명령 끝 부분 findRS="\0";awk 명령의 BEGIN 부분에 추가하십시오. 또한 파일 이름에 다음 항목이 포함되어 있지 않으면 "출력이 유효한 CSV가 아니라고 가정하지만 파일 이름에 다음 중 하나가 포함된 경우 "매개 변수가 너무 많습니다" 문제를 제외하고는 첫 번째 스크립트가 완벽하게 작동합니다. 그러면 확실히 실패합니다. 아니다.

답변2

그룹 명령(즉, and 내에 포함됨) 또는 하위 셸 내(즉, and 내에 포함됨)에서 and를 실행 find하고 실행하기 전에 헤더를 인쇄합니다. 전체 명령 그룹 또는 하위 셸의 출력을 출력 파일로 리디렉션합니다.awk{}()find

예를 들어:

{
  echo "Name,Number"
  find ./ -maxdepth 1 -type f -name '*.txt' -exec \
    awk -v OFS=, '
      FNR==1 { fn = FILENAME; sub(/^\.\//, "", fn };
     /value/ {print fn, $8}' {} +
} >> out.csv

노트:

  1. 보기 man bash및 검색Compound Commands
  2. 여기서는 그럴 필요가 없습니다 . 예를 들어 xargs찾기 옵션을 사용하세요 .-execfind ... -exec awk ... {} +
  3. awk 에는 .BTW 에서 파일을 제거 하는 기능이 sed내장되어 있으며 .sub()./findgsub()/gsed

관련 정보