Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/date/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/neo4j/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Shell unix awk从日期月份字段减去整数字段_Shell_Date_Unix_Awk - Fatal编程技术网

Shell unix awk从日期月份字段减去整数字段

Shell unix awk从日期月份字段减去整数字段,shell,date,unix,awk,Shell,Date,Unix,Awk,我有一个大约有10毫米记录的文件。这是我的dateSample src文件: 0000000566 2017/01/01 0 0000000055 2017/01/01 0 0000000109 2017/01/01 1 0000000940 2017/01/01 0 0000000566 2017/01/01 1 0000000055 2017/01/01 1 0000000109 2017/01/01 2 我基本上需要减去日期中月份的最后一个整数值,然后打印不带整数值的新值,因此: 000

我有一个大约有10毫米记录的文件。这是我的dateSample src文件:

0000000566 2017/01/01 0
0000000055 2017/01/01 0
0000000109 2017/01/01 1
0000000940 2017/01/01 0
0000000566 2017/01/01 1
0000000055 2017/01/01 1
0000000109 2017/01/01 2
我基本上需要减去日期中月份的最后一个整数值,然后打印不带整数值的新值,因此:

0000000566 2017/01/01
0000000055 2017/01/01
0000000109 2016/12/01
0000000940 2017/01/01
0000000566 2016/12/01
0000000055 2016/12/01
0000000109 2016/11/01
我在date(或macOS上的gdate)方面遇到了真正的问题,在过去几天里一直在徒劳地搜索。
它要么以零作为前缀,然后删除m和d值:

awk '{ print (gdate -d $2 +"%Y/%m/%d") }' <$src

awk'{print(gdate-d$2+%Y/%m/%d”)}'由于您正在处理日期,因此最好在shell本身中执行此操作:

while read -r str date n; do
   echo "$str $(date -d "$(date -d $date) -$n months" '+%Y/%m/%d')"
done < file

0000000566 2017/01/01
0000000055 2017/01/01
0000000109 2016/12/01
0000000940 2017/01/01
0000000566 2016/12/01
0000000055 2016/12/01
0000000109 2016/11/01
读取时-r str date n;做
echo“$str$(日期-d”$(日期-d$日期)-$n个月”+%Y/%m/%d')”
完成<文件
0000000566 2017/01/01
0000000055 2017/01/01
0000000109 2016/12/01
0000000940 2017/01/01
0000000566 2016/12/01
0000000055 2016/12/01
0000000109 2016/11/01

如果您的
awk
支持
mktime
strftime
(这是GNU扩展),您可以这样做:

awk -F'[ /]' '{print $1 " " strftime("%Y/%m/%d", mktime($2" "($3-$5)" "$4" 0 0 0"))}' file
首先,我们将日期转换为Unix时间戳
mktime
只接受
“YYYY-MM-DD-HH-MM-SS”格式的日期,这就是为什么我们需要手动构造它。但是它会自动进行标准化,并且它会很高兴地将
“2017-110 00”
转换为与
“2016 11 100 00”
相同的时间戳

之后,我们只需要将时间戳转换为“y/m/d”格式并打印它



或者,您可以在不需要日期规范化的简单情况下“手工”进行日期运算——如果月份的日期总是
,请尝试一种更简单的方法来解决此问题

awk 'BEGIN{
     split("01,02,03,04,05,06,07,08,09,10,11,12", month,",")
}
{
     split($2, array,"/");
       if(array[2]<=$3){
       array[2]=array[2]+12-$3;
       array[1]=array[1]-1
      }
       else{
       array[2]-$3
      };
     print $1,array[1]"/"array[2]"/"array[3]
}
'  Input_file
awk'开始{
拆分(“01,02,03,04,05,06,07,08,09,10,11,12”,月“,”)
}
{
拆分($2,数组“/”);

如果(数组[2]不会很慢,因为您在每行调用外部
date
(两次)?另外,您对
date
的内部调用不应该是:
$(date-d“$date”+%Y/%m/%d”)
?感谢@randomir它现在已经修复。您好……感谢上面的内容,但它在2017-05-01的日期不起作用。这里有一个调整版本:awk'{split($2,array,“/”);if($3>0){if(array[2]=“01”){array[1]=array[1]=array[2]+12-$3;if(array[2]<10){array[2]=“0”数组[2]}否则{array[2]=数组[2]-$3如果(数组[2]<10){array[2]=“0”数组[2]};}打印$1,数组[1]“/”数组[2]“/”数组[3]}“回复真棒……感谢您的详细解释。strftime-mktime组合非常好,运行速度非常快。还感谢“手动”版本的完整性。感谢您的帮助。干杯
while read -r str date n; do
   echo "$str $(date -d "$(date -d $date) -$n months" '+%Y/%m/%d')"
done < file

0000000566 2017/01/01
0000000055 2017/01/01
0000000109 2016/12/01
0000000940 2017/01/01
0000000566 2016/12/01
0000000055 2016/12/01
0000000109 2016/11/01
awk -F'[ /]' '{print $1 " " strftime("%Y/%m/%d", mktime($2" "($3-$5)" "$4" 0 0 0"))}' file
#!/usr/bin/awk -f

BEGIN {
    FS = "[ /]";
}

{
    mm = $2 * 12 + ($3 - 1) - $5;
    y = int(mm / 12);
    m = mm % 12 + 1;
    d = $4;
    printf("%s %04d/%02d/%02d\n", $1, y, m, d);
}
$ ./script.awk file
0000000566 2017/01/01
0000000055 2017/01/01
0000000109 2016/12/01
0000000940 2017/01/01
0000000566 2016/12/01
0000000055 2016/12/01
0000000109 2016/11/01
awk 'BEGIN{
     split("01,02,03,04,05,06,07,08,09,10,11,12", month,",")
}
{
     split($2, array,"/");
       if(array[2]<=$3){
       array[2]=array[2]+12-$3;
       array[1]=array[1]-1
      }
       else{
       array[2]-$3
      };
     print $1,array[1]"/"array[2]"/"array[3]
}
'  Input_file