解析日期和时间格式 - Bash
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/26753757/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Parsing date and time format - Bash
提问by onur
I have date and time format like this(yearmonthday):
我有这样的日期和时间格式(年月日):
20141105 11:30:00
I need assignment year, month, day, hour and minute values to variable.
我需要将年、月、日、小时和分钟值分配给变量。
I can do it year, day and hour like this:
我可以像这样在年、日和小时内做到这一点:
year=$(awk '{print }' log.log | sed 's/^\(....\).*//')
day=$(awk '{print }' log.log | sed 's/^.*\(..\).*//')
hour=$(awk '{print }' log.log | sed 's/^\(..\).*//')
How can I do this for month and minute?
我怎样才能在一个月和一分钟内做到这一点?
--
——
And I need that every line of my log file:
我需要我的日志文件的每一行:
20141105 11:30:00 /bla/text.1
20141105 11:35:00 /bla/text.2
20141105 11:40:00 /bla/text.3
....
I'm trying read line by line this log file and do this:
我正在尝试逐行读取此日志文件并执行以下操作:
mkdir -p "/bla/backup/$year/$month/$day/$hour/$minute"
mv $file "/bla/backup/$year/$month/$day/$hour/$minute"
Here is my not working code:
这是我不工作的代码:
#!/bin/bash
LOG=/var/log/LOG
while read line
do
year=${line:0:4}
month=${line:4:2}
day=${line:6:2}
hour=${line:9:2}
minute=${line:12:2}
file=$(awk '{print }')
if [ -f "$file" ]; then
printf -v path "%s/%s/%s/%s/%s" $year $month $day $hour $minute
mkdir -p "/bla/backup/$path"
mv $file "/bla/backup/$path"
fi
done < $LOG
采纳答案by glenn Hymanman
You don't need to call out to awk to date at all, use bash's substring operations
你根本不需要调用 awk 到 date,使用 bash 的 substring 操作
d="20141105 11:30:00"
yr=${d:0:4}
mo=${d:4:2}
dy=${d:6:2}
hr=${d:9:2}
mi=${d:12:2}
printf -v dir "/bla/%s/%s/%s/%s/%s/\n" $yr $mo $dy $hr $mi
echo "$dir"
/bla/2014/11/05/11/30/
Or directly, without all the variables.
或者直接,没有所有的变量。
printf -v dir "/bla/%s/%s/%s/%s/%s/\n" ${d:0:4} ${d:4:2} ${d:6:2} ${d:9:2} ${d:12:2}
Given your log file:
鉴于您的日志文件:
while read -r date time file; do
d="$date $time"
printf -v dir "/bla/%s/%s/%s/%s/%s/\n" ${d:0:4} ${d:4:2} ${d:6:2} ${d:9:2} ${d:12:2}
mkdir -p "$dir"
mv "$file" "$dir"
done < filename
or, making a big assumption that there are no whitespace or globbing characters in your filenames:
或者,假设文件名中没有空格或通配符:
sed -r 's#(....)(..)(..) (..):(..):.. (.*)#mv /blah/////#' | sh
回答by NeronLeVelu
eval "$(
echo '20141105 11:30:00' \
| sed 'G;s/\(....\)\(..\)\(..\) \(..\):\(..\):\(..\) *\(.\)/Year=Month=Day=Hour=Min=Sec=/'
)"
pass via a assignation string to evaluate. You could easily adapt to also check the content by replacing dot per more specific pattern like [0-5][0-9]
for min and sec, ...
通过分配字符串进行评估。您可以轻松地通过替换每个更具体的模式(例如[0-5][0-9]
分钟和秒)的点来检查内容,...
posix version so --posix
on GNU sed
posix 版本--posix
等 GNU sed
回答by Leslie Satenstein
I wrote a function that I usually cut and paste into my script files
我写了一个函数,我通常将它剪切并粘贴到我的脚本文件中
function getdate()
{
local a
a=(`date "+%Y %m %d %H %M %S" | sed -e 's/ / /'`)
year=${a[0]}
month=${a[1]}
day=${a[2]}
hour=${a[3]}
minute=${a[4]}
sec=${a[5]}
}
in the script file, on a line of it's own
在脚本文件中,在它自己的一行上
getdate
获取日期
echo "year=$year,month=$month,day=$day,hour=$hour,minute=$minute,second=$sec"
echo "year=$year,month=$month,day=$day,hour=$hour,minute=$minute,second=$sec"
Of course, you can modify what I provided or use answer [6] above. The function takes no arguments.
当然,您可以修改我提供的内容或使用上面的答案 [6]。该函数不接受任何参数。
回答by Kalanidhi
date
command also do this work
date
命令也做这个工作
#!/bin/bash
year=$(date +'%Y' -d'20141105 11:30:00')
day=$(date +'%d' -d'20141105 11:30:00')
month=$(date +'%m' -d'20141105 11:30:00')
minutes=$(date +'%M' -d'20141105 11:30:00')
echo "$year---$day---$month---$minutes"
回答by Jotne
You can use only one awk
您只能使用一个 awk
month=$(awk '{print substr(,5,2)}' log.log)
year=$(awk '{print substr(,0,4)}' log.log)
minute=$(awk '{print substr(,4,2)}' log.log)
etc
回答by Kent
I guess you are processing the log file, which each line starts with the date string. You may have already written a loop to handle each line, in your loop, you could do:
我猜您正在处理日志文件,其中每一行都以日期字符串开头。您可能已经编写了一个循环来处理每一行,在您的循环中,您可以执行以下操作:
d="$(awk '{print ,}' <<<"$line")"
year=$(date -d"$d" +%Y)
month=$(date -d"$d" +%m)
day=$(date -d"$d" +%d)
min=$(date -d"$d" +%M)
回答by gniourf_gniourf
Don't repeat yourself.
不要重复自己。
d='20141105 11:30:00'
IFS=' ' read -r year month day min < <(date -d"$d" '+%Y %d %m %M')
echo "year: $year"
echo "month: $month"
echo "day: $day"
echo "min: $min"
The trick is to ask date
to output the fields you want, separated by a character (here a space), to put this character in IFS
and ask read
to do the splitting for you. Like so, you're only executing date
once and only spawn one subshell.
诀窍是要求date
输出您想要的字段,由一个字符(这里是一个空格)分隔,将这个字符放入IFS
并要求read
为您进行拆分。像这样,您只执行date
一次并且只生成一个子shell。
If the date comes from the first line of the file log.log
, here's how you can assign it to the variable d
:
如果日期来自文件的第一行,以下是log.log
将其分配给变量的方法d
:
IFS= read -r d < log.log