-2

I need script to convert this holiday list into date format. My input file

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         

Now 123456789012345678901234567890 is like date when first time 0 comes it is 10 and then 1 means 11 and this is so on. ...

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

So I have created script where ever Y is present it convert into date suppose in first line Y is present under 1, 2,9,6,3,9

In my script i have cut each line from column 21- 52 and checking if that column is Y, if yes then it covert into date like if Y is present under column number 23. Then I am subratcing (coloumn number - 20) it will give me 3 And then i am using concat operatior to make date.

Below is my script. But i am facing issue when there is no Y under any coloumn it takes my var as blank and blank is also coming under true condition .

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

And my script is below.

 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`

Please let me know what I will do so that when there is nothing in var , it will not come under If condition true.

O/p of this script is that it convert all coloumn of each line from 21-52 into date not where Y is present.

Hope I clarify now.

  • Better you provide sample input and output – SHW Sep 26 '16 at 7:45
  • 1
    Check the formatting help in the question editing view, and put the code in code blocks so it displays properly. Also, what does the input look, exactly (and what should the output be)? Do you want to change every letter Y to something, or what? – ilkkachu Sep 26 '16 at 8:49
0

Okay, I copied your script below, and fixed the indentation so that it's a bit easier for me to read. (And I also changed the backticks to $() and removed the fixed file names because I like it that way.)

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

Two things jump up:

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

This doesn't work; it needs spaces around the equal sign. Try and see what [[ X=Y ]] && echo foo does.

Also, here

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

f1 contains something like 012016 821 YY Y Y Y Y, but since it’s not quoted, it gets expanded, then word-split along the spaces, after which echo prints all the words separated by single spaces, resulting in 012016 821 YY Y Y Y Y. You could fix it by adding the quotes: echo "$f1" | cut -c$i, but there's also "${f1:N:L}" to grab a substring of length L from position N. It is zero-indexed, though, so the range of $i will need to be modified.

Then,

echo "$year-$month-$date"

This could be changed to printf "%04d-%02d-%02d\n" "$year" "$month" "$date" to make sure the date is always printed with two digits, and to protect against possible anomalous values of $year.

Might as well move the month and year assignments to the outer loop, since they stay the same for the whole line.

Now we have:

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

The output looks about correct when I run it with 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
    ︙

Of course you seem to have all months doubled, so they are doubled in the output too. Perhaps add a test for the contents of the second column, or run it with something like this to check only lines with the given id:

grep DC holiday_india.txt | bash holiday.sh

(This would of course also skip the header lines. Or you could check that the month/year is sane at the beginning of the line.)

This was tagged with ksh, but I used bash. The copy of ksh I have supports ${foo:N:L}, which I think was the only new syntax I used.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.