使用unix shell脚本编辑csv文件中的列,具体取决于其列

时间:2017-04-09 15:36:10

标签: shell unix scripting

我的下表是csv格式的

  

07-04-2017,是
      08-04-2017,是
      09-04-2017,是
      10-04-2017,是
      11-04-2017,是
      07-04-2017,是

我希望将第一列与系统的当前日期进行比较,如果第一列中提到的日期是过去的,那么我想将第二列更改为" NO"。结果表是: -

  

07-04-2017,没有   08-04-2017,没有   09-04-2017,是
  10-04-2017,是
  11-04-2017,是
  07-04-2017,没有

我尝试了awk语句,但它没有比较日期。如果你知道如何解决这个问题,请分享命令。

3 个答案:

答案 0 :(得分:2)

试试这个 -

$awk -v date=$(date '+%d-%m-%Y') '{print ($1 < date?$1 FS "NO": $1 FS "YES")}' f
07-04-2017 NO
08-04-2017 NO
09-04-2017 YES
10-04-2017 YES
11-04-2017 YES
07-04-2017 NO

根据评论 - 今天该命令的结果 -

$awk -v date=$(date '+%d-%m-%Y') '{print ($1 < date?$1 FS "NO": $1 FS "YES")}' f
07-04-2017 NO
08-04-2017 NO
09-04-2017 NO
10-04-2017 YES
11-04-2017 YES
07-04-2017 NO

答案 1 :(得分:1)

如果我正确理解您的问题,则无需依赖任何其他实用程序。您可以使用POSIX shell 参数扩展子字符串删除来解析yearmonthday并将它们放入在重新格式化的日期字符串中,可以与date -d "string"一起使用以获取自纪元(1970-01-01 00:00:00 UTC)以来的秒数,并将其与当前日期/时间进行比较,以确定读取的日期是否为之前。然后,如果是,则可以输出"NO"

示例:

#!/bin/sh

while IFS=$' \t\n,' read -r fdate ans
do
    yr="${fdate##*-}"    ## parse year
    tmp="${fdate%-$yr}"  ## parse tmp="day-month"
    day="${tmp%-*}"      ## parse day
    mo="${tmp#*-}"       ## parse month
    rfdate="${yr}-${mo}-${day}"   ## create "year-mo-day" string

    ## compare date string with current day/time (seconds since epoch)
    if [ "$(date -d "$rfdate" +%s)" -lt "$(date +%s)" ]
    then
        echo "$fdate, NO"
    else
        echo "$fdate, $ans"
    fi
done < dat/dates 

示例输入

$ cat dat/dates
07-04-2017 ,YES
08-04-2017 ,YES
09-04-2017 ,YES
10-04-2017 ,YES
11-04-2017 ,YES
07-04-2017 ,YES

示例使用/输出

$ sh datebeforetst.sh <dat/dates
07-04-2017, NO
08-04-2017, NO
09-04-2017, NO
10-04-2017, NO
11-04-2017, YES
07-04-2017, NO

如果您需要考虑“今天”,例如(现在 - 24小时),您可以调整当天的比较方式:

if [ "$(date -d "$rfdate" +%s)" -lt "$(($(date +%s)-86400))" ]

导致输出:

$ sh datebeforetst.sh <dat/dates
07-04-2017, NO
08-04-2017, NO
09-04-2017, NO
10-04-2017, YES
11-04-2017, YES
07-04-2017, NO

答案 2 :(得分:0)

这是一个bash版本

#!/bin/bash

DATE=`date +%d-%m-%Y`
while read L
do
    D=`echo $L | cut -f1 -d\ `
    if [ $D \< $DATE ]
    then
        echo "$D NO"
    else
        echo "$D YES"
    fi
done <./dates.txt

全部在一行:

DATE=`date +%d-%m-%Y`; while read L; do D=`echo $L | cut -f1 -d\ `;[ $D \< $DATE ] && echo "$D NO" || echo "$D YES"; done <./dates.txt