Например, у меня есть файл данных как;
joze0670.14o
joze0680.14o
joze0690.14o
Я должен извлечь 3 цифры (день года) после первых 4 символов, и 2 цифры (год запускается с 2000), прежде "o". Затем я хочу найти день месяца года для каждых данных и присвоить их переменной.
Позвольте говорят, doy_1=067;year_1=2014
для первых данных. Затем переменные присвоены; year=2014;month=03;day=08
Я буду использовать эти переменные в цикле позже (как $year, $month, $day).
Что надлежащий путь к ним, обрабатывают?
Вы можете использовать комбинацию 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'
С помощью этого сценария
#!/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
Основная идея
Время эпохи Unix воздействует на секунды. Рев сценария извлекает год, преобразовывает первый день года ко времени эпохи Unix, смещает его (86 400 секунд в день) * (извлеченные дни - 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