이라는 이름의 수십만 개의 파일이 있는 폴더 hp-temps.txt
(및 수많은 하위 폴더)가 있습니다.
해당 파일의 내용은 다음과 같습니다.
Sensor Location Temp Threshold
------ -------- ---- ---------
#1 PROCESSOR_ZONE 15C/59F 62C/143F
#2 CPU#1 10C/50F 73C/163F
#3 I/O_ZONE 25C/77F 68C/154F
#4 CPU#2 32C/89F 73C/163F
#5 POWER_SUPPLY_BAY 9C/48F 55C/131F
모든 파일을 구문 분석하고 라인 #1에서 가장 높은 온도 항목을 찾아야 합니다.
작업 중인 스크립트가 있지만 시간이 오래 걸리고 이를 개선할 수 있는 방법이 있는지 알고 싶습니다.
저는 쉘 스크립팅을 처음 접했기 때문에 이 코드는 정말 비효율적이라고 생각합니다.
#!/bin/bash
highesetTemp=0
temps=$(find $1 -name hp-temps.txt -exec cat {} + | grep 'PROCESSOR' | cut -c 32-33)
for t in $temps
do
if [ $t -gt $highestTemp ]; then
highestTemp=$t
fi
done
편집하다:
매우 효율적인 코드가 있지만 가장 큰 값만 필요한 것은 아니라는 점을 언급하는 것을 잊어버렸습니다.
더 높은 값이 감지되면 파일의 디렉터리와 온도를 출력하고 싶기 때문에 모든 파일을 반복할 수 있기를 원합니다.
따라서 출력은 다음과 같습니다.
New MAX: 22 in /path/to/file/hp-temps.txt
New MAX: 24 in /another/path/hp-temps.txt
New MAX: 29 in /some/more/path/hp-temps.txt
답변1
중간 데이터를 문자열로 저장하는 것은 느리고 거의 필요하지 않습니다. 일반적인 경우 단일 스칼라 변수에 여러 문자열을 저장하는 데는 추가적인 문제가 있습니다. 이와 같이 각 하위 문자열에는 공백이나 기타 문자가 포함될 수 있으며 나중에 따옴표 없이 루프 방식을 사용하여 쉘을 강제로 사용하여 해결할 수 있습니다. 문자열을 분할합니다 for
(배열을 사용하는 것이 더 좋습니다).
이 경우 각 파일을 찾아 온도를 추출하고 해당 온도 스트림을 읽는 것이 더 효율적입니다. 또한 300KB(또는 그 이상)의 문자열을 포함하는 셸 변수 생성을 방지합니다.
섭씨 온도는 다음에서 분석할 수 있습니다.하나파일 사용량
awk '$2 == "PROCESSOR_ZONE" { printf "%d\n", $3 }' file
두 번째 필드가 문자열인 경우 세 번째 필드의 온도를 출력합니다 PROCESSOR_ZONE
. 쓰기 시 세 번째 필드를 정수로 변환하므로 값의 첫 번째 부분만 출력됩니다(숫자가 아닌 첫 번째 부분까지).
다음에서 호출됨 find
:
find . -name hp-temps.txt \
-exec awk '$2 == "PROCESSOR_ZONE" { printf "%d\n", $3 }' {} +
이는 awk
발견된 파일의 하나 이상의 배치에 대해 명령을 실행하고 표준 출력에 온도를 차례로 인쇄합니다.
awk
비표준 명령문을 이해하는 것을 사용하는 경우 nextfile
이를 사용하여 가능한 한 빨리 다음 파일로 이동할 수 있습니다.
find . -name hp-temps.txt \
-exec awk '$2 == "PROCESSOR_ZONE" { printf "%d\n", $3; nextfile }' {} +
위 명령으로 출력된 최대값을 찾으려면 다음 awk
명령을 사용할 수도 있습니다.
awk 'NR == 1 || $1 > max { max = $1 } END { print max }'
awk
max
변수 값이 지금까지 확인된 첫 번째 값이거나 가장 큰 값인 경우 현재 입력 값으로 설정합니다. 마지막 max
출력 값입니다.
나는 이것이 쉘 루프보다 몇 배 더 빠를 것으로 기대합니다.
종합해보면:
find . -name hp-temps.txt \
-exec awk '$2 == "PROCESSOR_ZONE" { printf "%d\n", $3; nextfile }' {} + |
awk 'NR == 1 || $1 > max { max = $1 } END { print max }'
가장 큰 값을 갖는 파일의 파일명을 찾아 달라는 추가 요청이 있습니다. 각 파일의 값과 함께 파일 이름을 전달하면 됩니다. 에서는 awk
현재 입력 파일의 경로 이름을 특수 변수로 사용할 수 있습니다 FILENAME
.
find . -name hp-temps.txt \
-exec awk '$2 == "PROCESSOR_ZONE" { printf "%d\t%s\n", $3, FILENAME; nextfile }' {} + |
awk 'NR == 1 || $1 > max { max = $1; fname = $2 } END { print max, fname }'
여러 파일의 최대값이 동일한 경우 발견된 첫 번째 파일의 파일 이름이 보고됩니다 find
. 유틸리티는 find
나열된 순서대로 파일을 찾습니다.ls -f