ホリデーテーブル作り

ホリデーテーブル作り

この休日リストを日付形式に変換するスクリプトが必要です。入力ファイル

MMYYYY CAL_B2K_ID   123456789012345678901234567890  
------ ------------ ------------------------------- 
012016 821          YY      Y      Y      Y      Y  
012016 DC           YY      Y      Y      Y      Y  
022016 DC                Y      Y      Y      Y     
022016 821               Y      Y      Y      Y     
032016 DC               Y      Y      Y      Y      
032016 821              Y      Y      Y      Y      
042016 821           Y      Y      Y      Y         

123456789012345678901234567890 は日付のようなもので、最初に 0 が来ると 10 となり、次に 1 が来ると 11 となり、これが続きます。...

 1 2 3 4 5 6 7 8 9 10 11 12 13 14............

そこで、Yが存在する場合は常に日付に変換するスクリプトを作成しました。最初の行でYが1、2、9、6、3、9の下に存在すると仮定します。

私のスクリプトでは、列 21 から 52 までの各行を切り取り、その列が Y であるかどうかをチェックしています。Y が列番号 23 の下に存在する場合のように、Y を日付に変換します。次に、(列番号 - 20) を減算すると、3 になります。次に、連結演算子を使用して日付を作成します。

以下は私のスクリプトです。ただし、どの列にも Y がない場合、var が空白として扱われ、true の条件でも空白になるという問題が発生しています。

var=echo $f1 | cut -c$i
if [[ "$var"='Y' ]] ;

私のスクリプトは以下の通りです。

 rm f1.txt
 set -x
 while read f1
 do
 for((i=21;i<23;i++));
 do
 var=`echo $f1 | cut -c$i`
 if [[ "$var"='Y' ]] ;
 then
 echo $var
 month=`echo $f1 | cut -c1-2`
 year=`echo $f1 |cut -c3-6`
 date=$(($i-20))
 echo $year"-"$month"-"$date >> f1.txt
 fi
done
done < holiday_india.txt`

var に何もない場合に、If 条件が true にならないようにするにはどうすればよいか教えてください。

このスクリプトの目的は、Y が存在する場所ではなく、21 から 52 までの各行のすべての列を日付に変換することです。

これで明確になったと思います。

答え1

わかりました。以下のスクリプトをコピーし、インデントを修正して、読みやすくしました。(また、バックティックを に変更し$()、固定ファイル名を削除しました。その方が好みだからです。)

while read f1 ; do
    for((i=21;i<23;i++)); do
        var=$(echo $f1 | cut -c$i)
        if [[ "$var"='Y' ]] ; then
            echo $var
            month=$(echo $f1 | cut -c1-2)
            year=$(echo $f1 |cut -c3-6)
            date=$(($i-20))
            echo "$year-$month-$date"
        fi
    done
done

2 つのことが浮かび上がります。

if [[ "$var"='Y' ]] ; then

これは機能しません。等号の前後にスペースが必要です。何が[[ X=Y ]] && echo foo機能するか試してください。

ここもまた

var=$(echo $f1 | cut -c$i)

f1のようなものが含まれています012016 821 YY Y Y Y Yが、引用符で囲まれていないため、展開され、スペースで単語が分割され、その後、echoで区切られたすべての単語が出力されます。シングルスペースが含まれ、 になります012016 821 YY Y Y Y Y。引用符を追加することでこれを修正できます: 、ただし、長さの部分文字列を取得する方法echo "$f1" | cut -c$iもあります"${f1:N:L}"位置からいいえただし、インデックスはゼロなので、 の範囲$iを変更する必要があります。

それから、

echo "$year-$month-$date"

これを に変更すると、printf "%04d-%02d-%02d\n" "$year" "$month" "$date"日付が常に 2 桁で印刷され、 の異常な値から保護されます$year

月と年の割り当ては行全体で同じままなので、外側のループに移動したほうがよいでしょう。

現在、次のようになっています。

while read f1; do
    month="${f1:0:2}"
    year="${f1:2:4}"
    for (( i=20 ; i < 20 + 31 ; i++ )); do
        var="${f1:$i:1}"
        if [[ "$var" = "Y" ]] ; then
            date=$(( $i - 19 ))
            printf "%04d-%02d-%02d\n" "$year" "$month" "$date"
        fi
    done
done

次のように実行すると、出力はほぼ正しいように見えますbash holiday.sh < holiday_india.txt:

2016-01-01
2016-01-02
2016-01-09
2016-01-16
2016-01-23
2016-01-30
2016-01-01

もちろん、すべての月が 2 倍になっているようですので、出力でも 2 倍になっています。2 番目の列の内容のテストを追加するか、次のように実行して、指定された ID の行のみをチェックしてください。

grep DC holiday_india.txt | bash holiday.sh

(もちろん、これによりヘッダー行もスキップされます。または、行の先頭で月/年が適切であることを確認することもできます。)

これは ksh でタグ付けされていますが、私は bash を使用しました。ksh私が持っている のコピーは をサポートしており、これが私が使用した唯一の新しい構文だと思います。${foo:N:L}

関連情報