PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Bash-Skript: Problem bei Argumentverarbeitung



Raptor
31-08-2004, 11:29
Hab ein kleines Problem mit einem Bash-Skript.
Um das Programm /usr/bin/cal ein bisschen handlicher zu machen,
dass es auch als Argument alphanumerische Monateund nicht nur
numerische nimmt hab ich das hier gescriptet.


case $# in
0) set `date`;m=$2;y=$6;;
1) m=$1;set `date`;y=$6;;
*) m=$1;y=$2;;
esac

case $m in
jan*|Jan*) m=1;;
feb*|Feb*) m=2;;
mar*|Mar*) m=3;;
apr*|Apr*) m=4;;
may*|May*) m=5;;
jun*|Jun*) m=6;;
jul*|Jul*) m=7;;
aug*|Aug*) m=8;;
sep*|Sep*) m=9;;
oct*|Oct*) m=10;;
nov*|Nov*) m=11;;
dec*|Dec*) m=12;;
[1-9]|10|11|12) ;;
*) y=$m; m="";;
esac

/usr/bin/cal $m $y
Jetzt will ich auch, dass man mehrere Monate angeben kann
cal oct nov 2004
oder ranges angeben kann
cal jan - dec 2004

Ich krieg das aber mit der Argumentverarbeitung nicht hin
und komme immer durcheinander und vergesse einen Fall zu beruecksichtigen

any help?

thx in advance

Raptor

peschmae
31-08-2004, 12:10
Am besten guckst du die Argumente einfach mit "shift" durch und jedes mal wenn du einen Monat findest guckst du ob das nächste Argument ein "-" wäre
und wenn ja hast du einen Bereich gefunden.
Ansonsten gibts denke ich nicht viel spezielles - du gehst ja wohl davon aus dass das letzte das Jahr ist.

MfG Peschmä

Raptor
31-08-2004, 14:39
du gehst ja wohl davon aus dass das letzte das Jahr ist.
..Nein.

*) y=$m; m="";;

Das mit den ranges war auch eher das kleinere Problem. Was mir kopfzerbrechen beritet ist das angeben mehrerer Monate....

peschmae
31-08-2004, 15:17
mehrere Monate heisst dann mehrere cal-Aufrufe, d.h. für jeden Monat einen?

Und gehst du davon aus dass nur ein Jahr angegeben wird?
d.h. ist sowas möglich:
jan 2004 jan 2005
was dann Januar 2004 und 2005 ausgeben würde?
Wenn ja, was soll mit einem
2004 jan 2006
geschehen?

Wenn nur eine Jahrangabe möglich ist ist das wohl relativ einfach - am besten suchst du da zuerst das Jahr raus und guckst dann für den Rest der Parameter immer obs ein einzelner Monat oder ein Bereich ist - die Sachen kannst du dann ja sofort ausgeben weil du das Jahr schon kennst.

MfG Peschmä

Raptor
31-08-2004, 16:02
d.h. ist sowas möglich:
jan 2004 jan 2005 nein.


mehrere Monate heisst dann mehrere cal-Aufrufe, d.h. für jeden Monat einen?

cal nov oct 2004 Das ist momentan das Problem

peschmae
31-08-2004, 16:39
Nein, ich meine das "richtige" cal.

Mal ein Vorschlag, noch ohne die Bereiche:


#!/bin/bash

checkVar() {
case $1 in
jan*|Jan*) m=1;;
feb*|Feb*) m=2;;
mar*|Mar*) m=3;;
apr*|Apr*) m=4;;
may*|May*) m=5;;
jun*|Jun*) m=6;;
jul*|Jul*) m=7;;
aug*|Aug*) m=8;;
sep*|Sep*) m=9;;
oct*|Oct*) m=10;;
nov*|Nov*) m=11;;
dec*|Dec*) m=12;;
[1-9]|10|11|12) ;;
*) return ;;
esac

echo ARGS: $m $VAR
/usr/bin/cal $m $VAR

}

VAR=$(date +%Y)
for f in $*; do
if [[ $f =~ \^[1-2][0-9][0-9][0-9]\$ ]] ; then
VAR=$f
fi
done

echo Jahr $VAR

while [ -n "$*" ] ; do
checkVar $1
shift
done



MfG Peschmä

Raptor
31-08-2004, 16:53
eingentlich muesstest du das selbst auch haben.. einfach mal '
man cal'


CAL(1) System General Commands Manual CAL(1)

NAME
cal, ncal - displays a calendar and the date of easter

SYNOPSIS
cal [-jy] [[month] year]
ncal [-jJpwy] [-s country_code] [[month] year]
ncal [-Jeo] [year]

DESCRIPTION
Cal displays a simple calendar in traditional format and ncal offers an
alternative layout, more options and the date of easter. The new format
is a little cramped but it makes a year fit on a 25x80 terminal. If
arguments are not specified, the current month is displayed.

The options are as follows:

-J Display Julian Calendar, if combined with the -e option, display
date of easter according to the Julian Calendar.

-e Display date of easter (for western churches).

-j Display Julian days (days one-based, numbered from January 1).

-o Display date of orthodox easter (Greek and Russian Orthodox
Churches).

-p Print the country codes and switching days from Julian to Grego-
rian Calendar as they are assumed by ncal. The country code as
determined from the local environment is marked with an asterisk.

-s country_code
Assume the switch from Julian to Gregorian Calendar at the date
associated with the country_code. If not specified, ncal tries
to guess the switch date from the local environment or falls back
to September 2, 1752. This was when Great Britain and her
colonies switched to the Gregorian Calendar.

-w Print the number of the week below each week column.

-y Display a calendar for the current year.

A single parameter specifies the year (1 - 9999) to be displayed; note
the year must be fully specified: ``cal 89'' will not display a calendar
for 1989. Two parameters denote the month (1 - 12) and year.

A year starts on Jan 1.

SEE ALSO
calendar(3), strftime(3)

HISTORY
A cal command appeared in v6 UNIX. The ncal command appeared in
FreeBSD 2.2.6.

AUTHORS
The ncal command and manual were written by Wolfgang Helbig
<helbig@FreeBSD.org>.

BUGS
The assignment of Julian - Gregorian switching dates to country codes is
historically naive for many countries.

BSD December 16, 1997 BSD
~
~
(stdin):

peschmae
31-08-2004, 16:55
Und wer sagt dir dass mein Cal dasselbe ist wie deines?

MfG Peschmä

Raptor
31-08-2004, 18:48
Weil es schon seit ueber 20 Jahren nahezu unveraendert ist.

peschmae
31-08-2004, 19:21
Nahezu ;)
Aber du hast wohl recht, das scheint ja von BSD zu kommen und die GNUler haben da ausnamsweise nicht viel geändert.

Btw. bash wird geändert und obiges Script braucht bash >= 3.0

MfG Peschmä

tuNIxM1TUniX
01-09-2004, 08:34
keine Lösung, nur ein Ansatz:



ArgIsMonth=0

case $m in
jan*|Jan*) m[ArgIsMonth]=1 ; ArgIsMonth=$((ArgIsMonth++)) ;;
feb*|Feb*) m[ArgIsMonth]=2 ; ArgIsMonth=$((ArgIsMonth++)) ;;
mar*|Mar*) m[ArgIsMonth]=3 ; ArgIsMonth=$((ArgIsMonth++)) ;;
apr*|Apr*) m[ArgIsMonth]=4 ; ArgIsMonth=$((ArgIsMonth++)) ;;
may*|May*) m[ArgIsMonth]=5 ; ArgIsMonth=$((ArgIsMonth++)) ;;
jun*|Jun*) m[ArgIsMonth]=6 ; ArgIsMonth=$((ArgIsMonth++)) ;;
jul*|Jul*) m[ArgIsMonth]=7 ; ArgIsMonth=$((ArgIsMonth++)) ;;
aug*|Aug*) m[ArgIsMonth]=8 ; ArgIsMonth=$((ArgIsMonth++)) ;;
sep*|Sep*) m[ArgIsMonth]=9 ; ArgIsMonth=$((ArgIsMonth++)) ;;
oct*|Oct*) m[ArgIsMonth]=10 ; ArgIsMonth=$((ArgIsMonth++)) ;;
nov*|Nov*) m[ArgIsMonth]=11 ; ArgIsMonth=$((ArgIsMonth++)) ;;
dec*|Dec*) m[ArgIsMonth]=12 ; ArgIsMonth=$((ArgIsMonth++)) ;;
[1-9]|10|11|12) ;;
*) y=$m; m="";;
esac

So hast du erstmal die Anzahl aller übergebenen Monatsangaben und brauchst "nur noch" die cal-Argumente zu basteln...

edit:
Entschuldigung, die Syntax oben ist falsch!
Muss natürlich heißen:

dec*|Dec*) m[$((ArgIsMonth++))]=12;;
oder

dec*|Dec*) m[ArgIsMonth]=12 ; ArgIsMonth=$((ArgIsMonth+1)) ;;