파일의 마지막 줄을 [지속적으로] 읽는 방법은 무엇입니까?

파일의 마지막 줄을 [지속적으로] 읽는 방법은 무엇입니까?

클라이언트가 라이브 MQTT 스트림에서 데이터를 필터링하고 파일에 데이터를 쓰도록 했습니다 myfile.csv. 다음은 마지막 네 줄입니다.

1426134425,m,NWRL,MSV,001,d,SVlts,139,1840343,26089,28529,15987
1426134444,m,NWRL,MSV,001,d,status,139,1859000,23911,-33.836465,151.051189
1426134834,m,gf,TMX6BP,075,d,SVlts,216,1243746,27209,27409,17106
1426134845,m,gf,TMX6BP,075,d,status,216,1254000,179583,-33.836465,151.051189

이 문서는 지속적으로 업데이트됩니다. 따라서 csv 파일의 마지막 줄은 계속 변경되지만 형식은 동일하게 유지됩니다.

묻다:myfile.csv일곱 번째 값이 "SVlts" 대신 "status"인 bash를 사용하여 파일의 마지막 줄을 어떻게 읽을 수 있습니까 ? 이 내용을 읽은 후 4번째, 5번째, 10번째 값을 3개의 다른 변수에 어떻게 할당합니까? 이 값을 푸시하여 MySQL 테이블을 업데이트하겠습니다.

따라서 출력은 다음과 같습니다.

variable_1=TMX6BP
variable_2=075
variable_3=179583

언급한 대로, 이 세 가지 변수는 다음 행이 인쇄될 때까지 MySQL 테이블(자체 업데이트가 필요함)을 업데이트하기 위해 푸시/전송됩니다 myfile.csv. 그리고 이는 반복해서 발생합니다.

답변1

그러면 마지막 줄에서 원하는 정보가 캡처됩니다 file.

$ IFS=, read -r a b c var_1 var_2 d e f h var_3 extra < <(tail -n1 file)
$ echo $var_1  $var_2  $var_3
TMX6BP 075 179583

어떻게 작동하나요?

  • IFS=,

    그러면 필드 구분 기호가 일시적으로 쉼표로 설정됩니다.

  • read -r a b c var_1 var_2 d e f h var_3 extra

    그러면 필드를 나열된 변수로 읽어 들입니다. 원하는 이름을 선택할 수 있습니다.

    위에서 첫 번째 필드는 쉘 변수에 할당되고 a두 번째 필드는 에 할당됩니다 b. 그 이후에 남은 모든 것은 var_3쉘 변수에 할당됩니다 extra.

  • < <(tail -n1 file)

    file이는 명령의 표준 입력으로 마지막 줄을 제공합니다 read. 첫 번째는 <리디렉션에 사용되는 쉘 기호입니다. 이 구성을 <(...)프로세스 대체라고 합니다. 첫 번째와 두 번째 사이의 간격은 다음 <과 같습니다.기초적인.

답변2

짧은 답변:

   # tail -F: output appended data as the file grows
   #      Capital F to follow even if the file is reset to zero, recreated, etc.
   # awk -F, sets FS - Field Separator to a comma
   #   Inside awk: See if field 7 == "status" and print fields 4, 5 and 10
tail -F myfile.csv | awk -F, '$7 == "status" { print $4, $5, $10 }'

데이터베이스 업데이트 방법을 작성하지 않았으므로 시작하는 데 도움이 될 내용을 작성하겠습니다.

내가 이해한 바에 따르면 myfile.csv 파일을 편집하지 않고 업데이트 스크립트/작업에 대한 입력으로 언급된 3개 변수를 사용합니다. 오류 확인 등은 여러분께 맡기겠습니다.

먼저 MySQL 데이터베이스를 업데이트하는 스크립트를 만듭니다. 여기서는 그냥 웃겠습니다.

#!/bin/bash
# update-MySQL-table.sh
    # redirecting stderr to stdout so awk will see it.
    # Not much use with "echo", but ...
echo $0 $1 $2 $3 2>&1

그런 다음 CSV 파일을 읽고 구문 분석하고 데이터베이스 업데이트 스크립트를 시작하는 또 다른 스크립트가 있습니다.

#!/bin/bash
# parse-my-CSV-file.sh
csvfile="myfile.csv"

tail -n0 -F $csvfile | \
    awk -F, '
        $7 == "status" {
            cmd=sprintf("./update-MySQL-table.sh %s %s %s",$4,$5,$10)
            cmd | getline output
            print output
    }'

그런 다음 구문 분석 스크립트를 시작하면 일곱 번째 필드에 "status"가 있는 myfile.csv에 추가된 새 줄이 어떻게 stdout에 인쇄되는지 확인해야 합니다.

답변3

나는 다음과 같은 일을 할 것입니다 :

tail -n1 -f file | 
  perl -MDBI -F, -lane 'BEGIN{$d = DBI->connect(...)}
    if ($F[6] eq "status") {
      $d->do("INSERT INTO foo VALUES (?,?,?)", @F[3,4,9]);
    }'

관련 정보