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 foo
funktioniert.
Auch hier
var=$(echo $f1 | cut -c$i)
f1
enthä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 echo
werden 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 $i
muss 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 „ ksh
Ich habe“ unterstützt , was, glaube ich, die einzige neue Syntax war, die ich verwendet habe.${foo:N:L}