CSV 파일을 입력 및 출력하기위한 Bash 스크립트 / awk

Sep 28 2020

세 열 (이름, 성, 생년월일)의 쉼표로 구분 된 CSV 파일을 가져오고 입력에서 동일한 열이있는 다른 CSV 파일을 출력하는 bash / awk / sed 스크립트를 만드는 데 문제가 있습니다. 현재 날짜와 생년월일 간의 차이를 연도 단위로 표시하는 추가 열.

$ yourscript <input CSV file> <output CSV file>

input.csv는 다음과 같습니다.

bob,wag,06/13/1958
ashley,hay,01/23/1983
evan,bert,09/11/1972

output.csv는 다음과 같아야합니다.

bob,wag,06/13/1958,62
ashley,hay,01/23/1983,37
evan,bert,09/11/1972,48

답변

3 Cbhihe Sep 28 2020 at 14:46
$ cat data
bob,wag,06/13/1958
ashley,hay,01/23/1983
evan,bert,09/11/1972

이름이 지정된 파일로 출력 output-file하고 동시에 STDOUT에 표시하려면 다음을 수행하십시오.

$ awk -v year=$(\date +%Y) 'BEGIN{FS="/"} {print $0 "," year-$3}' data | tee output-file
bob,wag,06/13/1958,62
ashley,hay,01/23/1983,37
evan,bert,09/11/1972,48

또는 동일한 파일로 출력하려면 :

$ awk -v year=$(\date +%Y) 'BEGIN{FS="/"} {print $0 "," year-$3}' data > output-file
2 Cbhihe Sep 30 2020 at 18:04

보다 정확한 시간 계산을 수행하려면 gawk의 시간 및 문자열 함수를 사용할 수 있습니다 (@AdminBee의 제안에 따라). 입력 데이터를 다음과 같이 사용 :

$ cat data
bob,wag,06/13/1958
ashley,hay,01/23/1983
evan,bert,09/11/1972

당신의 시간 차이를 얻을 수있는 일을 지금까지의 날짜로, 각 라인에 표시 :

$ awk -F, 'BEGIN{today=systime()} 
           {print $0 "," int((today-mktime(substr($3,7,4)" "substr($3,1,2)" "substr($3,4,2)" "00" "00" "00))/(3600*24))}' \
           data | tee output-file

 bob,wag,06/13/1958,22755
 ashley,hay,01/23/1983,13765
 evan,bert,09/11/1972,17551

스 니펫 :

int((today-mktime(substr($3,7,4)" "substr($3,1,2)" "substr($3,4,2)" "00" "00" "00))/(3600*24))

입력 파일의 각 줄에 대해 세 가지 기본 작업을 수행합니다.

  • 1970-01-01 00:00:00 UTC (POSIX 시스템에서) 이후 경과 된 시간 (초)을 계산하며 윤초는 계산하지 않습니다. mktime(substr($3,7,4)" "substr($3,1,2)" "substr($3,4,2)" "00" "00" "00)
  • today1970-01-01 00:00:00 UTC 이후 실행 시점에 경과 된 시간 (초)을 포함 하는 위의 수량과 변수 간의 시간 차이를 계산합니다 .
  • 초 단위의 시간 차이를 3600 * 24로 나누어 일 단위로 동일하게하고 결과의 정수 부분 만 고려하여 int().

필요에 따라 초, 분, 시간 단위로 시차를 얻을 수 있습니다. HTH

MaheshK. Sep 28 2020 at 11:49

날짜 차이를 얻으려면이 작은 bash 함수를 사용할 수 있습니다.

필요에 따라 다음 번호를 사용하십시오.

  • # 일 차이를 얻으려면 : 86400
  • # 년 차이를 얻으려면 : 31536000

배쉬 기능

datediff() {
  current_date=$(date -d "$1" +%s)
  birth_date=$(date -d "$2" +%s)
  echo $(( (current_date - birth_date) / 31536000)) Years
}

용법:

datediff '9/28/2020' '1/1/1999'

산출:

 21 years
MarcinŚlusarz Jan 09 2021 at 09:58

정말로 원하는 것에 따라 :

년 차이 :

(echo "firstname,lastname,d"; cat input.csv) | csv-sqlite \
 "select *, strftime('%Y', 'now') - substr(d, 7, 4) as year_diff
  from input" | csv-header --remove

나이:

(echo "firstname,lastname,d"; cat input.csv) | csv-sqlite
  "select *, strftime('%Y', 'now') - substr(d, 7, 4) -
             case when strftime('%m%d', 'now') >= (substr(d, 1, 2) || substr(d, 4, 2))
             then 0 else 1 end as age
  from input" | csv-header --remove

csv-sqlite 및 csv-header는 csv-nix-tools 에서 가져온 것입니다.