2

助けが必要です。csv の Date (文字列) 列を 1 日増やしたいと思います。例 (日付形式 yyyy-MM-dd)

Col1,Col2,Col3
ABC,001,1900-01-01
XYZ,002,2000-01-01

期待されるアウトプット

Col1,Col2,Col3
ABC,001,1900-01-02
XYZ,002,2000-01-02
4

3 に答える 3

3

1752 年 9 月 14 日から 9999 年 12 月 31 日までのすべての日付マジックが組み込まれている標準的な Unix ユーティリティが1 つあります: calendarcalです。車輪を再発明して面倒な日付計算を行う代わりに、そのインテリジェンスを有利に利用します。基本的な問題は次のとおりです。与えられた日付は月の最後の日ですか? そうでない場合は、単に日を増やします。はいの場合は、日を 1 にリセットし、月 (場合によっては年) を増やします。

ただし、の出力calは指定されておらず、次のようになります。

$ cal 2 1900
   February 1900
Su Mo Tu We Th Fr Sa
             1  2  3
 4  5  6  7  8  9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28

必要なのは、1 2 3 ... 28 の日のリストです。これを行うには、「1」までのすべてをスキップします。

 set -- $(cal 2 1900)
 while test $1 != 1; do shift; done

args の数は、1900 年 2 月の日数を示します。

 $ echo $#
 28

すべてをスクリプトにまとめると、次のようになります。

#!/bin/sh

read -r header
printf "%s\n" "$header"

while IFS=,- read -r col1 col2 y m d; do
  case $m-$d in
    (12-31) y=$((y+1)) m=01 d=01;;
    (*)
      set -- $(cal $m $y)
      # Shift away the month and weekday names.
      while test $1 != 1; do shift; done
      # Is the day the last day of a month?
      if test ${d#0} -eq $#; then
        # Yes: increment m and reset d=01.
        m=$(printf %02d $((${m#0}+1)))
        d=01
      else
        # No: increment d.
        d=$(printf %02d $((${d#0}+1)))
      fi
    ;;
  esac
  printf "%s,%s,%s-%s-%s\n" "$col1" "$col2" $y $m $d
done

この入力で実行します。

Col1,Col2,Col3
ABC,001,1900-01-01
ABC,001,1900-02-28
ABC,001,1900-12-31
XYZ,002,2000-01-01
XYZ,002,2000-02-28
XYZ,002,2000-02-29

収量

Col1,Col2,Col3
ABC,001,1900-01-02
ABC,001,1900-03-01
ABC,001,1901-01-01
XYZ,002,2000-01-02
XYZ,002,2000-02-29
XYZ,002,2000-03-01

-最初の 2 列にはコンマまたはエスケープされたカンマが含まれていないという仮定を 1 つ立てました。もしそうなら、IFS=,- readは行動します。

于 2013-05-31T12:37:17.020 に答える