나는 명령을 가지고 있습니다 :
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
명령 끝 부분 find
과 RS="\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
노트:
- 보기
man bash
및 검색Compound Commands
- 여기서는 그럴 필요가 없습니다 . 예를 들어
xargs
찾기 옵션을 사용하세요 .-exec
find ... -exec awk ... {} +
- awk 에는 .BTW 에서 파일을 제거 하는 기능이
sed
내장되어 있으며 .sub()
./
find
gsub()
/g
sed