节日餐桌制作

节日餐桌制作

我需要脚本将此假期列表转换为日期格式。我的输入文件

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}

相关内容