使用awk / sed更改第一列中的日期格式

时间:2012-12-04 12:23:36

标签: linux sed awk

我有一个shell脚本,每天早上会自动运行,并将该天数结果附加到文本文件中。该文件应该在第一列上有今天的日期,后面跟逗号分隔的结果。我使用命令日期+%x来获取所需格式的日期(年/月/日)。但是在一台计算机日期+%x返回mm / dd / yyyy(任何想法为什么会这样?)。然后,我按日期顺序对文件中的数据进行排序。

以下是此类文本文件的片段

29/11/12,9654.80,194.32,2.01,7.19,-7.89,7.65,7.57,3.98,9625.27,160.10,1.66,4.90,-4.79,6.83,4.84,3.54                
03/12/12,5184.22,104.63,2.02,6.88,-6.49,7.87,6.67,4.10,5169.52,93.81,1.81,5.29,-5.45,7.87,5.37,4.10                
04/12/12,5183.65,103.18,1.99,6.49,-6.80,8.40,6.66,4.38,5166.04,95.44,1.85,6.04,-6.49,8.40,6.28,4.38                
11/07/2012,5183.65,102.15,1.97,6.78,-6.36,8.92,6.56,4.67,5169.48,96.67,1.87,5.56,-6.10,8.92,5.85,4.67                
07/11/2012,5179.39,115.57,2.23,7.64,-6.61,8.83,7.09,4.62,5150.17,103.52,2.01,7.01,-6.08,8.16,6.51,4.26                
11/26/2012,5182.66,103.30,1.99,7.07,-5.76,7.38,6.37,3.83,5162.81,95.47,1.85,6.34,-5.40,6.65,5.84,3.44                
11/30/2012,5180.82,95.19,1.84,6.51,-5.40,7.91,5.92,4.12,5163.98,91.82,1.78,5.58,-5.07,7.05,5.31,3.65     

是否可以使用awk或sed将后四行的日期格式更改为正确的日期格式?我只希望将格式为mm / dd / yyyy的日期格式更改为dd / mm / yy。

5 个答案:

答案 0 :(得分:5)

看起来你正在使用date的两种不同风格(版本)。要检查您的版本,我认为GNU date接受--version标记,而BSD/OSX等其他版本则不接受此标记。

由于您可能使用完全不同的系统,因此最安全地避免date并使用perl打印当前日期可能是最安全的:

perl -MPOSIX -e 'print POSIX::strftime("%d/%m/%y", localtime) . "\n"'

如果您确定两台计算机上都有GNU awk,则可以像这样使用它:

awk 'BEGIN { print strftime("%d/%m/%y") }'

要修复您所拥有的文件,请使用GNU awk

awk '{ print gensub(/^(..\/)(..\/)..(..,)/, "\\2\\1\\3", "g"); next }1' file

或使用sed

sed 's/^\(..\/\)\(..\/\)..\(..,\)/\2\1\3/' file

结果:

29/11/12,9654.80,194.32,2.01,7.19,-7.89,7.65,7.57,3.98,9625.27,160.10,1.66,4.90,-4.79,6.83,4.84,3.54                
03/12/12,5184.22,104.63,2.02,6.88,-6.49,7.87,6.67,4.10,5169.52,93.81,1.81,5.29,-5.45,7.87,5.37,4.10                
04/12/12,5183.65,103.18,1.99,6.49,-6.80,8.40,6.66,4.38,5166.04,95.44,1.85,6.04,-6.49,8.40,6.28,4.38                
07/11/12,5183.65,102.15,1.97,6.78,-6.36,8.92,6.56,4.67,5169.48,96.67,1.87,5.56,-6.10,8.92,5.85,4.67                
11/07/12,5179.39,115.57,2.23,7.64,-6.61,8.83,7.09,4.62,5150.17,103.52,2.01,7.01,-6.08,8.16,6.51,4.26                
26/11/12,5182.66,103.30,1.99,7.07,-5.76,7.38,6.37,3.83,5162.81,95.47,1.85,6.34,-5.40,6.65,5.84,3.44                
30/11/12,5180.82,95.19,1.84,6.51,-5.40,7.91,5.92,4.12,5163.98,91.82,1.78,5.58,-5.07,7.05,5.31,3.65

答案 1 :(得分:2)

这应该有效:sed -re 's/^([0-9][0-9])\/([0-9][0-9])\/[0-9][0-9]([0-9][0-9])(.*)$/\2\/\1\/\3\4/'

它可以做得更小但是我这样做了它会更明显它做什么(4组,只是切换月/日并删除当年的前两个字符)。

提示:如果您不希望cat该文件,您可以使用in place进行更改sed -i。但是如果你把一个错误的表达式放在最后你可能会破坏你的源文件,请小心。

注意:这假设如果年份指定为4位数,则月/日相反。

答案 2 :(得分:1)

以下命令将执行此操作。

注意:无论文件中有多少行。这只会改变最后4行。

tail -r your_file| awk -F, 'NR<5{split($1,a,"/");$1=a[2]"/"a[1]"/"a[3];print}1'|tail -r

我可以在不使用管道和使用单个awk语句的情况下找出某种方法,这个解决方案确实需要一个tail命令:

awk -F, 'BEGIN{cmd="wc -l your_file";while (cmd|getline tmp);split(tmp,x)}x[1]-NR<=4{split($1,a,"/");$1=a[2]"/"a[1]"/"a[3];print}1' your_file

答案 3 :(得分:1)

另一种解决方案:

awk -F/ 'NR<4;NR>3{a=$1;$1=$2;$2=a; print $1"/"$2"/" substr($3,3,2) substr($3,5)}' file

答案 4 :(得分:-1)

使用awk:

$ awk -F/ 'NR>3{x=$1;$1=$2;$2=x}1' OFS="/" file

通过使用/作为分隔符,您需要做的就是使用临时变量交换第1和第2个字段。