sed/awk/grep 명령을 사용하여 txt 파일의 값 편집

sed/awk/grep 명령을 사용하여 txt 파일의 값 편집

저는 La Crosse WS2350 기상 관측소를 5년 동안 사용해 왔습니다. 기상 관측소에서 제공하는 데이터는 RPI의 open2300을 사용하여 처리됩니다. 이것은 매우 잘 작동합니다. 그런데 온도 데이터(센서)가 잘못되었습니다. 온도 데이터는 1°C 낮습니다.

센서를 교정할 수 없어서 기상 관측소에서 추출한 파일의 온도 값을 변경하고 싶습니다.

텍스트 파일(current.txt)에는 다음이 포함됩니다.

Date 2016-Dec-03
Time 10:30:29
Ti 11.9
Timin 11.6
Timax 27.7
TTin 10:34
DTimin 2016-01-19
TTimax 00:44
DTimax 2016-08-28
To -2.4
Tomin -4.8
Tomax 37.4
TTomin 06:46
DTomin 2016-02-18
TTomax 16:13
DTomax 2016-07-19
...

"To", "Tomin", "Tomax" 값에 +1을 추가하고 텍스트 파일을 올바른 값으로 덮어쓰고 싶습니다.

sed 및 awk 명령을 살펴본 후 나는 내가 최신 버전이 아니라는 것을 깨달았습니다. 누구든지 나를 안내할 수 있나요? 감사해요

편집하다:

다른 파일인 ws2308.log를 잊어버렸습니다. 15분마다 ws2308.log 파일에 새 줄이 추가됩니다.

...
20161203150600 2016-Dec-03 15:06:00 11.8 -1.1 -3.2 65 87 0.0 157.5 SSE -1.1 569.80 1015.700 
20161203152100 2016-Dec-03 15:21:00 12.3 -1.1 -3.2 64 87 0.0 157.5 SSE -1.1 569.80 1015.600 
20161203153600 2016-Dec-03 15:36:00 12.2 -1.2 -3.3 64 87 0.0 135.0 SE -1.2 569.80 1015.700 

수정해야 할 값은 다섯 번째 필드(첫 번째 -1.2)입니다.

또한 마지막 행의 온도 값에 1을 더하고 마지막 행을 올바른 값으로 덮어써야 합니다. 프로그램 PHP는 마지막 행만 고려하며 결과를 차트에 표시할 수 있습니다.

감사해요

답변1

이는 처리하기 위한 약간 더 관용적인 AWK 변형입니다 current.txt(스티브의 두 번째 대답더욱 관용적입니다! ):

awk '/^To(|min|max) / { print $1, $2 + 1; next } 1' current.txt

To이는 로 시작 하고 뒤에 뭔가 min또는 가 오는 행을 찾고 max, 그 뒤에 공백이 오는 행을 찾습니다. 일치하는 행에 대해 첫 번째 필드와 두 번째 필드가 증가하면서 기본 출력 필드 구분 기호(공백)로 구분되어 인쇄됩니다. 그런 다음 다음 줄로 점프합니다. 다른 모든 줄은 있는 그대로 인쇄됩니다( 1AWK의 단축키입니다).

새 값으로 파일을 덮어쓰는 것은 아마도 좋은 생각이 아닐 것입니다. 값이 수정되었는지 알 수 없습니다... 매번 장치에서 파일을 검색하는 경우에는 적용되지 않습니다.

동일한 추론이 적용되므로 ws2308.log매번 완전히 처리합니다.

$ awk 'NF >= 5 { $5 = $5 + 1 } 1' ws2308.log
20161203150600 2016-Dec-03 15:06:00 11.8 -0.1 -3.2 65 87 0.0 157.5 SSE -1.1 569.80 1015.700
20161203152100 2016-Dec-03 15:21:00 12.3 -0.1 -3.2 64 87 0.0 157.5 SSE -1.1 569.80 1015.600
20161203153600 2016-Dec-03 15:36:00 12.2 -0.2 -3.3 64 87 0.0 135.0 SE -1.2 569.80 1015.700

마지막 행만 원하는 경우:

$ awk 'NF >= 5 { $5 = $5 + 1; lastline = $0 } END { print lastline }' ws2308.log
20161203153600 2016-Dec-03 15:36:00 12.2 -0.2 -3.3 64 87 0.0 135.0 SE -1.2 569.80 1015.700

또는 마지막 줄만 포함된 파일을 원하는 경우변경됨:

$ awk 'length(prevline) > 0 { print prevline } NF >= 5 { prevline = $0; $5 = $5 + 1; lastline = $0 } END { print lastline }' ws2308.log
20161203150600 2016-Dec-03 15:06:00 11.8 -1.1 -3.2 65 87 0.0 157.5 SSE -1.1 569.80 1015.700 
20161203152100 2016-Dec-03 15:21:00 12.3 -1.1 -3.2 64 87 0.0 157.5 SSE -1.1 569.80 1015.600 
20161203153600 2016-Dec-03 15:36:00 12.2 -0.2 -3.3 64 87 0.0 135.0 SE -1.2 569.80 1015.700

답변2

이것이 해결책입니다. "To", "Tomin" 또는 "Tomax"로 시작하고 뒤에 공백이 오는 줄의 경우 첫 번째 필드를 인쇄한 다음 두 번째 필드를 1씩 증가시킵니다. 그렇지 않으면 전체 줄만 인쇄됩니다.

$ awk '{if(/^(To|Tomin|Tomax) /){print $1 " " $2+1}else{print $0}}' w.txt
Date 2016-Dec-03
Time 10:30:29
Ti 11.9
Timin 11.6
Timax 27.7
TTin 10:34
DTimin 2016-01-19
TTimax 00:44
DTimax 2016-08-28
To -1.4
Tomin -3.8
Tomax 38.4
TTomin 06:46
DTomin 2016-02-18
TTomax 16:13
DTomax 2016-07-19
$

답변3

또 다른 방법은 약간 골프를 치다.

$ awk '/^To/{$2++}1' w.txt
Date 2016-Dec-03
Time 10:30:29
Ti 11.9
Timin 11.6
Timax 27.7
TTin 10:34
DTimin 2016-01-19
TTimax 00:44
DTimax 2016-08-28
To -1.4
Tomin -3.8
Tomax 38.4
TTomin 06:46
DTomin 2016-02-18
TTomax 16:13
DTomax 2016-07-19
$

답변4

그러면 다음이 수행됩니다.

  1. 먼저 모든 행을 반복합니다.
  2. 그런 다음 첫 번째 항목을 확인하고 요구 사항을 충족하는지 확인하십시오.
  3. 그런 다음 일치하면 인쇄하고 줄의 다음 항목에 +1을 추가합니다.
  4. 그렇지 않으면 그냥 인쇄하고 다음 항목을 인쇄하세요.

    awk '{
        for(i=1;i<=NF;i++) {
                t+=$i;if(i==1){
                        if($i=="To" ||$i=="Tomin" ||$i=="Tomax"  ){
                                printf  "%s ",$i;
                                print $(i+1)+1;}
    
                        else{
                                print $0
                                }
                        }
                        };
        }' current.txt
    

산출

Date 2016-Dec-03
Time 10:30:29
Ti 11.9
Timin 11.6
Timax 27.7
TTin 10:34
DTimin 2016-01-19
TTimax 00:44
DTimax 2016-08-28
To -1.4
Tomin -3.8
Tomax 38.4
TTomin 06:46
DTomin 2016-02-18
TTomax 16:13
DTomax 2016-07-19

관련 정보