3

我有一个每天早上自动运行的 shell 脚本,它将当天的结果附加到一个文本文件中。该文件的第一列应该有今天的日期,后面是用逗号分隔的结果。我使用命令 date +%x 以所需格式 (dd/mm/yy) 获取日期。但是在一台计算机上 date +%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。

4

5 回答 5

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
于 2012-12-04T13:50:34.260 回答
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 位数字,则月/日是相反的。

于 2012-12-04T12:31:49.300 回答
1

另一种解决方案:

awk -F/ 'NR<4;NR>3{a=$1;$1=$2;$2=a; print $1"/"$2"/" substr($3,3,2) substr($3,5)}' file
于 2012-12-05T16:50:29.190 回答
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
于 2012-12-04T12:53:17.757 回答
-1

使用 awk:

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

通过使用 / 作为分隔符,您需要做的就是交换第一个和第二个字段,这在此处使用临时变量完成。

于 2012-12-04T12:34:46.800 回答