例如我有一个像这样的数据文件;
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
您可以使用和的组合sed
:xargs
date
$ 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