Bash script / awk เพื่อป้อนและส่งออกไฟล์ CSV
ฉันมีปัญหาในการสร้างสคริปต์ bash / awk / sed ที่จะใช้ไฟล์ CSV ที่คั่นด้วยจุลภาคสามคอลัมน์ (ชื่อนามสกุลวันเดือนปีเกิด) และส่งออกไฟล์ CSV อื่นที่มีคอลัมน์เดียวกันจากอินพุตด้วย คอลัมน์เพิ่มเติมที่แสดงความแตกต่างระหว่างวันที่ปัจจุบันและวันเดือนปีเกิดในปี
$ 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
คำตอบ
$ 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
เพื่อดำเนินการคำนวณเวลาที่ถูกต้องมากขึ้นคุณสามารถใช้gawk's เวลาและสตริงฟังก์ชั่น (ต่อ @ ข้อเสนอแนะของ 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) - จะคำนวณความแตกต่างของเวลาระหว่างปริมาณข้างต้นและตัวแปร
todayซึ่งประกอบด้วยจำนวนวินาทีที่ผ่านไปในขณะดำเนินการตั้งแต่ 1970-01-01 00:00:00 UTC - มันแบ่งความแตกต่างในเวลาไม่กี่วินาทีโดย 3600 * 24
int()จะได้รับเดียวกันในวันและพิจารณาเฉพาะส่วนจำนวนเต็มของผลที่จะได้รับทั้งวันด้วย
คุณสามารถเล่นด้วยเพื่อให้เวลาของคุณแตกต่างกันเป็นวินาทีนาทีชั่วโมงตามความต้องการของคุณ HTH
เพื่อให้ได้ความแตกต่างของวันที่คุณสามารถใช้ฟังก์ชันทุบตีขนาดเล็กนี้
ใช้หมายเลขต่อไปนี้สำหรับความต้องการของคุณ
- # เพื่อรับความแตกต่างของวัน : 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
ขึ้นอยู่กับสิ่งที่คุณต้องการจริงๆ:
ความแตกต่างของปี:
(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