Festtagstisch gestalten

Festtagstisch gestalten

Ich brauche ein Skript, um diese Feiertagsliste in das Datumsformat umzuwandeln. Meine Eingabedatei

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         

Nun ist 123456789012345678901234567890 wie ein Datum, wenn zum ersten Mal eine 0 kommt, ist es 10, dann ist 1 11 und so weiter. …

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

Also habe ich ein Skript erstellt, bei dem jedes Y in ein Datum umgewandelt wird. Angenommen, in der ersten Zeile steht Y unter 1, 2, 9, 6, 3, 9.

In meinem Skript habe ich jede Zeile aus den Spalten 21 bis 52 ausgeschnitten und geprüft, ob diese Spalte Y ist. Wenn ja, wird sie in ein Datum umgewandelt, als ob Y in Spalte 23 vorhanden wäre. Dann subtrahiere ich (Spaltennummer – 20), was mir 3 ergibt. Und dann verwende ich den Concat-Operator, um das Datum zu erstellen.

Unten ist mein Skript. Aber ich habe ein Problem, wenn in keiner Spalte ein Y steht, wird meine Variable als leer angenommen und ein Leerzeichen tritt auch unter der Bedingung „true“ auf.

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

Und mein Skript ist unten.

 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`

Bitte lassen Sie mich wissen, was ich tun werde, damit die If-Bedingung nicht erfüllt wird, wenn in var nichts steht.

Der Vorteil dieses Skripts besteht darin, dass es alle Spalten jeder Zeile von 21-52 in ein Datum umwandelt, nicht dort, wo Y vorhanden ist.

Hoffe, ich habe das jetzt klargestellt.

Antwort1

Okay, ich habe Ihr Skript unten kopiert und die Einrückung korrigiert, damit es für mich etwas leichter zu lesen ist. (Und ich habe auch die Backticks geändert $()und die festen Dateinamen entfernt, weil es mir so gefällt.)

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

Zwei Dinge fallen auf:

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

Das funktioniert nicht. Um das Gleichheitszeichen herum sind Leerzeichen erforderlich. Probieren Sie es aus und sehen Sie, was [[ X=Y ]] && echo foofunktioniert.

Auch hier

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

f1enthält etwas wie 012016 821 YY Y Y Y Y, aber da es nicht in Anführungszeichen steht, wird es erweitert, dann werden die Wörter entlang der Leerzeichen getrennt und anschließend echowerden alle Wörter durcheinzelLeerzeichen, was zu ergibt 012016 821 YY Y Y Y Y. Sie können es beheben, indem Sie die Anführungszeichen hinzufügen: echo "$f1" | cut -c$i, aber es gibt auch die Möglichkeit, einen Teilstring der Länge"${f1:N:L}"Mvon PositionN. Es ist jedoch nullindiziert, daher $imuss der Bereich geändert werden.

Dann,

echo "$year-$month-$date"

Dies könnte geändert werden, um printf "%04d-%02d-%02d\n" "$year" "$month" "$date"sicherzustellen, dass das Datum immer mit zwei Ziffern gedruckt wird, und um vor möglichen anomalen Werten zu schützen $year.

Die Monats- und Jahreszuweisungen können auch in die äußere Schleife verschoben werden, da sie in der gesamten Zeile gleich bleiben.

Jetzt haben wir:

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

Die Ausgabe sieht ungefähr korrekt aus, wenn ich sie mit folgendem ausführe 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

Natürlich scheinen Sie alle Monate verdoppelt zu haben, also werden sie auch in der Ausgabe verdoppelt. Fügen Sie vielleicht einen Test für den Inhalt der zweiten Spalte hinzu oder führen Sie ihn mit etwas wie diesem aus, um nur Zeilen mit der angegebenen ID zu überprüfen:

grep DC holiday_india.txt | bash holiday.sh

(Dadurch würden natürlich auch die Kopfzeilen übersprungen. Oder Sie könnten prüfen, ob der Monat/das Jahr am Zeilenanfang sinnvoll ist.)

Dies war mit ksh getaggt, aber ich habe bash verwendet. Die Kopie von „ kshIch habe“ unterstützt , was, glaube ich, die einzige neue Syntax war, die ich verwendet habe.${foo:N:L}

verwandte Informationen