如何使用shell转换为日期格式(DD-MMM-YYYY)?

如何使用shell转换为日期格式(DD-MMM-YYYY)?,shell,awk,Shell,Awk,我在一个文件中有数据,其中一列是日期列,其日期格式如下: 2021-05-10T18:25:00.000+0100 2021-05-14T18:25:00.000+0100 2021-05-19T18:25:00.000+0100 预期输出为: 10 MAY 2021 14 MAY 2021 19 MAY 2021 while -r read line do year=`echo $line | awk '{ print $1 }' ` month=`echo $line |

我在一个文件中有数据,其中一列是日期列,其日期格式如下:

2021-05-10T18:25:00.000+0100
2021-05-14T18:25:00.000+0100
2021-05-19T18:25:00.000+0100
预期输出为:

10 MAY 2021
14 MAY 2021
19 MAY 2021
while -r read line
do
    year=`echo $line | awk '{ print $1 }' `
    month=`echo $line | awk '{ print $2 }' `
    dt=`echo $line | awk '{ print $3 }' `

    v=$dt"-"$month"-"$year
    d=date '`$v' | dd-mm-yyyy
    echo $d
done < /f/filename.txt
我尝试过的方法:

10 MAY 2021
14 MAY 2021
19 MAY 2021
while -r read line
do
    year=`echo $line | awk '{ print $1 }' `
    month=`echo $line | awk '{ print $2 }' `
    dt=`echo $line | awk '{ print $3 }' `

    v=$dt"-"$month"-"$year
    d=date '`$v' | dd-mm-yyyy
    echo $d
done < /f/filename.txt
while-r读取行
做
年份=`echo$line | awk'{print$1}'`
月份=`echo$line | awk'{print$2}'`
dt=`echo$line | awk'{print$3}'`
v=$dt“-“$month”-“$year”
d=日期“`v”| dd mm yyyy
echo$d
完成
对于您的示例,请尝试以下操作:

awk -F'[T-]' '
BEGIN{
  num=split("Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sept,Oct,Nov,Dec",month,",")
}
{
  mon=substr($2,2,1)
}
(mon in month){
  print $3,month[mon],$1
}
' Input_file
awk -F'[T-]' '
BEGIN{
  num=split("Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sept,Oct,Nov,Dec",month,",")
}
($2+0 in month){
  print $3,month[$2+0],$1
}
' Input_file
或者尝试以下操作:

awk -F'[T-]' '
BEGIN{
  num=split("Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sept,Oct,Nov,Dec",month,",")
}
{
  mon=substr($2,2,1)
}
(mon in month){
  print $3,month[mon],$1
}
' Input_file
awk -F'[T-]' '
BEGIN{
  num=split("Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sept,Oct,Nov,Dec",month,",")
}
($2+0 in month){
  print $3,month[$2+0],$1
}
' Input_file
解释:为上述代码添加详细解释:

awk -F'[T-]' '             ##Starting awk program from here and setting field separator as - OR T here for all Lines.
BEGIN{                     ##Starting BEGIN section of this program here.
  num=split("Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sept,Oct,Nov,Dec",month,",") ##Creating month array here which has month names here.
}
{
  mon=substr($2,2,1)       ##Creating variable mon, which has sub string of 2nd field with 1st character.
}
(mon in month){            ##Checking if mon is present in month then do following.
  print $3,month[mon],$1   ##Printing 3rd field, month value 1st field.
}
' Input_file               ##Mentioning Input_file name here.
另一种方法:

awk -F'[T-]' 'BEGIN{                         
                mon="JanFebMarAprMayJunJulAugSepOctNovDec"

              # if need uppercase use below variable
              # mon="JANFEBMARAPRMAYJUNJULAUGSEPOCTNOVDEC"
              }
              {
                print $3,substr(mon,($2*3)-2,3), $1
              }' file
测试结果:

输入:

$ cat file 
2021-01-10T18:25:00.000+0100
2021-02-14T18:25:00.000+0100
2021-03-19T18:25:00.000+0100
2021-04-19T18:25:00.000+0100
2021-05-19T18:25:00.000+0100
2021-06-19T18:25:00.000+0100
2021-07-19T18:25:00.000+0100
2021-08-19T18:25:00.000+0100
2021-09-19T18:25:00.000+0100
2021-10-19T18:25:00.000+0100
2021-11-19T18:25:00.000+0100
2021-12-19T18:25:00.000+0100
输出:

$ awk -F'[T-]' 'BEGIN{mon="JanFebMarAprMayJunJulAugSepOctNovDec"}{print $3,substr(mon,($2*3)-2,3), $1}' file
10 Jan 2021
14 Feb 2021
19 Mar 2021
19 Apr 2021
19 May 2021
19 Jun 2021
19 Jul 2021
19 Aug 2021
19 Sep 2021
19 Oct 2021
19 Nov 2021
19 Dec 2021

您在尝试中遇到了许多语法和设计问题

我并不特别推荐使用shell来实现这一点;对于这个特定的任务,使用普通的
date
和Awk及Perl等解决方案的其他答案无疑更好,无论是在可用性、可读性还是性能方面。但是在某些情况下,您确实希望或需要使用shell,因此理解正确的语法是很重要的

因此,对于记录,shell完全能够将空白处的输入行或设置为
的任何内容拆分为变量

你的
d
作业中也有一些特殊的打字错误。我在这里疯狂地猜测你到底是什么意思

而IFS='-T'读取-r年-月dt;
做
日期-d“$year-$month-$dt”+%d%b%Y”
完成
d=datewhich
会将文本字符串
date
分配给变量
d
,然后尝试将
which
作为命令运行,可能会失败。当然,创建一个变量只是为了能够立即
echo

date-d
是GNU变体;在*BSD(包括macOS)上,您需要类似于2021-05-28的
date-j-f%Y-%m-%d+%d%b%Y

我不认为strftime提供了月份名称的大写版本;如果大喊大叫对你来说很重要,那就用烟斗吧

done <file | tr a-z A-Z

使用
perl
完成:

$perl-MTime::Piece-lne'$t=Time::Piece->strtime(substr($,0,10),%F”);
打印$t->strftime(“%d%b%Y”)“ip.txt
2021年5月10日
2021年5月14日
2021年5月19日
  • substr($,0,10)
    将给出前10个字符
  • %F
    相当于
    %Y-%m-%d
  • %d%b%Y
    所需的输出格式
  • 有关文档,请参阅

为了可读性,我使用了两条语句,单语句版本如下所示:

perl-MTime::Piece-lne'打印时间::Piece->strtime(substr($,0,10),“%F”)->strtime(“%d%b%Y”)'

GNU coreutils
date
命令支持您拥有的输入格式,例如:

date -f filename.txt +'%d %b %Y'
输出:

2021年5月10日
2021年5月14日
2021年5月19日
如果你想把它装在所有的瓶盖上,就用管子把它穿过去


注意:使用GNU coreutils的8.30版进行测试。

使用
GNU awk
,这可以在一行中完成:

awk'{
打印时间(strftime(“%d%b%Y”),mktime(gensub(/[-:T]/,”“,“g”))
}"档案"
2021年5月10日
2021年5月14日
2021年5月19日
或不带
gensub

awk-F'[-:T]'{$1=$1;打印头文件(strftime(“%d%b%Y”,mktime($0))}

我相信我们之前已经为您介绍了这一点,但是:a)请阅读和b)请复制/粘贴您的脚本,并在将其发布到此处之前修复它告诉您的问题,这样我们就不必查看和解释该工具可能告诉您的问题。
2021-05-11T01:00:00.000+0100
2021-05-10T23:00:00.000-0100
是同时。您希望输出哪个日期?请注意,由于ISO 8601,以破折号作为分隔符的
数字形式写入的日期应采用
YYYY-MM-DD
格式。如果您需要其他格式,请使用其他格式作为分隔符,例如空格或斜杠。什么shell?在什么平台上(包括版本)?我喜欢你的解决方案。你能把上面的命令变成通用的吗。。我的文件为4列名称| DATE | CITY | COURSE->so DATE将出现在第二列中,在这种情况下,在不干扰其他列的情况下,我希望格式化DATE列data@codeholic24:可以通过粘贴和剪切来完成。然而,这可能应该在一个新的问题中用准确的输入数据来提问