節慶餐桌製作

節慶餐桌製作

我需要腳本將此假期清單轉換為日期格式。我的輸入文件

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 列下一樣。進行減法(列號- 20),它將給我 3 然後我使用 concat 運算子來製作日期。

下面是我的腳本。但我面臨的問題是,當任何列下都沒有 Y 時,它會將我的 var 作為空白,並且空白也在真實條件下出現。

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 的情況下。

該腳本的 O/p 是將每行從 21-52 的所有列轉換為日期,而不是 Y 存在的位置。

希望我現在澄清一下。

答案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

有兩件事跳了起來:

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}"L從位置。但它是零索引的,因此$i需要修改的範圍。

然後,

echo "$year-$month-$date"

可以將其變更為,printf "%04d-%02d-%02d\n" "$year" "$month" "$date"以確保日期始終以兩位數字列印,並防止可能的異常值$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

當然,你似乎所有月份都加倍了,所以它們的產出也加倍了。也許添加對第二列內容的測試,或者使用類似這樣的內容運行它以僅檢查具有給定 id 的行:

grep DC holiday_india.txt | bash holiday.sh

(這當然也會跳過標題行。或者您可以檢查行開頭的月份/年份是否正常。)

這是用 ksh 標記的,但我使用的是 bash。kshI have support的副本,我認為這是我使用的唯一新語法。${foo:N:L}

相關內容