Праздничный стол сделать

Праздничный стол сделать

Мне нужен скрипт для преобразования этого списка праздников в формат даты. Мой входной файл

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 ни под одним столбцом, он принимает мою переменную как пустую, а пустая также попадает под условие 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.

Особенность этого скрипта в том, что он преобразует все столбцы каждой строки с 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}"Лс позицииН. Однако индексация равна нулю, поэтому диапазон $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

Конечно, у вас, похоже, все месяцы удвоены, поэтому они удвоены и в выводе. Возможно, добавьте тест для содержимого второго столбца или запустите его с чем-то вроде этого, чтобы проверить только строки с указанным идентификатором:

grep DC holiday_india.txt | bash holiday.sh

(Конечно, это также пропустит строки заголовков. Или вы можете проверить правильность месяца/года в начале строки.)

Это было помечено как ksh, но я использовал bash. Копия kshI have поддерживает , что, как мне кажется, было единственным новым синтаксисом, который я использовал.${foo:N:L}

Связанный контент