从文本文件中提取特定数字并转换为年月日

从文本文件中提取特定数字并转换为年月日

例如我有一个像这样的数据文件;

joze0670.14o
joze0680.14o
joze0690.14o

我需要在前 4 个字符后提取 3 位数字(年份中的日期),并在“o”前提取 2 位数字(年份从 2000 年开始)。然后,我要找出每个数据的年月日,并将它们分配给变量。

假设doy_1=067;year_1=2014是第一个数据。然后分配变量;year=2014;month=03;day=08

我稍后将在循环中使用这些变量(如$year、$month、$day)。

这些过程的正确方法是什么?

答案1

您可以使用和的组合sedxargsdate

$ sed -r 's/.{4}([0-9]{3}).*/\1/' input | xargs -i date -d '2014-01-01 + {} days - 1 day' '+%Y %m %d'
2014 03 08
2014 03 09
2014 03 10

然后您可以将read值放入变量中:

sed -r 's/.{4}([0-9]{3}).*/\1/' input | xargs -i date -d '2014-01-01 + {} days - 1 day' '+%Y %m %d' | 
  while read year month day
  do
     echo "Year: $year"
     echo "Month: $month"
     echo "Day: $day"
  done 

参考:


先前的代码使用了固定年份。要使用扩展提供的年份,我们可以sed创建一个完整的日期字符串date

sed -r 's/.{4}([0-9]{3}).\.([0-9]{2}).*/20\2-01-01 + \1 days - 1 day/' input | xargs -i date -d {} '+%Y %m %d'

答案2

通过此脚本

#!/usr/bin/env bash
while read -r line; do 
    year=$(sed 's/^.\{4,4\}\([0-9]\{3,3\}\)0\.\(.*\)o/\1 \2/' <(echo "$line") | awk '{system("date -d \"01/01/"$2" +"$1" days -1 days\" +\"%Y\"")}')
    month=$(sed 's/^.\{4,4\}\([0-9]\{3,3\}\)0\.\(.*\)o/\1 \2/' <(echo "$line") | awk '{system("date -d \"01/01/"$2" +"$1" days -1 days\" +\"%m\"")}')
    day=$(sed 's/^.\{4,4\}\([0-9]\{3,3\}\)0\.\(.*\)o/\1 \2/' <(echo "$line") | awk '{system("date -d \"01/01/"$2" +"$1" days -1 days\" +\"%d\"")}')
done <foo

例子

#!/usr/bin/env bash
while read -r line; do 
    year=$(sed 's/^.\{4,4\}\([0-9]\{3,3\}\)0\.\(.*\)o/\1 \2/' <(echo "$line") | awk '{system("date -d \"01/01/"$2" +"$1" days -1 days\" +\"%Y\"")}')
    month=$(sed 's/^.\{4,4\}\([0-9]\{3,3\}\)0\.\(.*\)o/\1 \2/' <(echo "$line") | awk '{system("date -d \"01/01/"$2" +"$1" days -1 days\" +\"%m\"")}')
    day=$(sed 's/^.\{4,4\}\([0-9]\{3,3\}\)0\.\(.*\)o/\1 \2/' <(echo "$line") | awk '{system("date -d \"01/01/"$2" +"$1" days -1 days\" +\"%d\"")}')

    echo "$year"
    echo "$month"
    echo "$day"
done <foo

给出输出

2014
03
08
2014
03
09
2014
03
10

答案3

基本理念

Unix 纪元时间以秒为单位。下面的脚本提取年份,将年份的第一天转换为 unix 纪元时间,将其偏移 (每天 86400 秒) * (提取的天数 - 1),然后将其转换回人类可读的格式

脚本

#!/bin/bash
#set -x
SECONDSINYEAR=86400

while  read line && [[ -n $line ]];do
   ARRAY=( $( awk -F '.' '!/^$/{gsub(/[a-z,A-Z]/,""); print substr($1,1,3),$2 }' <<< "$line") )
   ARRAY[0]=$( expr ${ARRAY[0]} - 1  )
   DAYOFFSET=$( expr ${ARRAY[0]} \* 86400 )
   BASEDATE=$(date -d ${ARRAY[1]}0101 +%s)
   ACTUALDATE=$( expr $BASEDATE + $DAYOFFSET )

   date -d "@$ACTUALDATE" +%d" "%m" "%Y

done  < $1

输出

xieerqi:$ cat testFile.txt                                                
joze0670.14o
joze0680.14o
joze0690.14o


xieerqi:$ ./extractDate.sh testFile.txt                                   
08 03 2014
09 03 2014
10 03 2014

相关内容