2012-02-05 5 views
5

Starając się osiągnąć następujące zmagał zdanie:Konwersja uniksowego `cal` wyjścia do kodu tabeli latex: jedno rozwiązanie liniowej?

Konwersja Unix cal wyjście do kodu tabeli lateks, stosując krótkie i słodkie jedną wkładkę (lub kilka-liner).

Np cal -h 02 2012 | $magicline powinna przynieść

Mo  &Tu  &We  &Th  &Fr  \\ 
     &  & 1  & 2  & 3  \\ 
6  & 7  & 8  & 9  &10  \\ 
13  &14  &15  &16  &17  \\ 
20  &21  &22  &23  &24  \\ 
27  &28  &  &  &  \\ 

jedynym rozsądnym rozwiązaniem mogłem wymyślić do tej pory było

cal -h | sed -r -e '1d' -e \ 
    's/^(..)?(...)?(...)?(...)?(...)?(...)?(...)?$/\2\t\&\3\t\&\4\t\&\5\t\&\6\t\\\\/' 

... i naprawdę starał. Zaletą jest to, że jest nieskomplikowany i łatwy do zrozumienia, co jest złym faktem, że jest "nieelastyczny" (nie radził sobie z 8-dniowym tygodniem) i trochę gadatliwy. Szukam alternatywnych rozwiązań, aby uczyć się od ;-)

EDIT: znaleźć inny, który wydaje się do zaakceptowania

cal -h | tail -n +2 | 
    perl -ne 'chomp; 
     $,="\t&"; 
     $\="\t\\\\\n"; 
     $line=$_; 
     print map {substr($line,$_*3,3)} (1..5)' 

EDIT: Nice one:

cal -h | perl \ 
    -F'(.{1,3})' -ane \ 
     'BEGIN{$,="\t&";$\="\t\\\\\n"} 
      next if $.==1; 
      print @F[3,5,7,9,11]' 
+2

Kod golf ma własne forum SE. – tripleee

+1

Która wersja 'cal', na której platformie akceptuje opcję' -h'? –

+0

@ Jonathan: wydaje się, że tylko [wersja calowa Ubuntu] (http://manpages.ubuntu.com/manpages/gutsy/man1/cal.1.html) jest jedyną. – Borodin

Odpowiedz

2

Korzystanie z wersji GNU awk:

Moje wyjście cal używając angielskiego LANG.

Command:

LANG=en_US cal 

wyjściowa:

February 2012 
Su Mo Tu We Th Fr Sa 
      1 2 3 4 
5 6 7 8 9 10 11 
12 13 14 15 16 17 18 
19 20 21 22 23 24 25 
26 27 28 29 

awk jedna linia:

LANG=en_US cal | awk ' 
BEGIN { 
    FIELDWIDTHS = "3 3 3 3 3 3 3"; 
    OFS = "&"; 
} 
FNR == 1 || $0 ~ /^\s*$/ { next } 
{ 
    for (i=2; i<=6; i++) { 
    printf "%-3s%2s", $i, i < 6 ? OFS : "\\\\"; 
    } 
    printf "\n"; 
}' 

Wynik:

Mo &Tu &We &Th &Fr \\ 
    & & 1 & 2 & 3 \\ 
6 & 7 & 8 & 9 &10 \\ 
13 &14 &15 &16 &17 \\ 
20 &21 &22 &23 &24 \\ 
27 &28 &29 & & \\ 
+1

dobre podejście, dzięki za bit '' FIELDWIDTHS'. Co powiesz na 'cal | awk 'BEGIN {FIELDWIDTHS = "3 3 3 3 3 3 3"; OFS = "\ t &"; ORS = "\ t \\\\\ n";} FNR! = 1 {wydrukuj 2 USD, 3 USD, 4 USD, 5 USD, 6 USD;} "'? –

-1

Po awk 1 wkładka powinna działać:

cal 02 2012 | awk 'NR>1 && NF>0 { 
    if (NR==2) 
     col=NF; 
    j=1; 
    if (NR==3 && NF<col) { 
     if (NF<col) 
     printf(" & "); 
     for(j=2; j<=col-NF; j++) 
     printf(" &"); 
    } 
    for (i=j; i<=col; i++) { 
     if (j==1 && i==j) 
     printf("%2s ", $(i-j+1)); 
     else 
     printf(" %3s", "&" $(i-j+1)); 
    } 
    printf(" \\\\\n"); 
}' 

WYJŚCIE:

Su &Mo &Tu &We &Th &Fr &Sa \\ 
& & & &1 &2 &3 &4 \\ 
5 &6 &7 &8 &9 &10 &11 \\ 
12 &13 &14 &15 &16 &17 &18 \\ 
19 &20 &21 &22 &23 &24 &25 \\ 
26 &27 &28 &29 & & & \\ 
+0

Niestety, nie ma. 1 lutego 2012 r. To środa, a nie niedziela! –

+0

Pls sprawdź edytowaną odpowiedź teraz. – anubhava

-1
cal -h 02 2012| cut -c4-17 | sed -r 's/(..)\s/\0\t\&/g' | sed 's/$/\t\\\\/' | head -n-1 | tail -n +2 

To będzie produkować:

Mo  &Tu  &We  &Th  &Fr \\ 
     &  & 1  & 2  & 3 \\ 
6  & 7  & 8  & 9  &10 \\ 
13  &14  &15  &16  &17 \\ 
20  &21  &22  &23  &24 \\ 
27  &28  &29  &  &  \\ 

można łatwo zastąpić \t z liczbą miejsc chcesz

+0

Nie, nie ma (nie tworzy żadnych komórek po "29") ... –

+0

@JoSo, cóż, robi tak, jeśli używasz 4 spacji zamiast '\ t', tak jak wkleiłem tutaj dane wyjściowe. –

-1

To działa dla mojego wykonania cal, który używa czteroznakowych kolumn i ma początkowy wiersz tytułu pokazujący miesiąc i rok

cal | perl -pe "next if $.==1;s/..../$&&/g;s/&$/\\\\/" 

Wygląda to tak, jakby twój może mieć kolumny osiem znaków i nie ma wiersz tytułowy, w którym to przypadku

cal | perl -pe "s/.{8}/$&&/g;s/&$/\\\\/" 

powinno załatwić sprawę, ale bądź przygotowany, aby go dostosować.

+0

Niestety, nie tworząc pustej komórki przez kilka dni, które są już w przyszłym miesiącu ... Chociaż rozszerzenie linii na początku może ją naprawić. Dziękuję za przełącznik '-p'. –

3

Testowane na OS-X:

cal 02 2012 |grep . |tail +2 |perl -F'/(.{3})/' -ane \ 
    'chomp(@F=grep $_,@F); $m=$#F if !$m; printf "%s"."\t&%s"x$m."\t\\\\\n", @F;' 

Gdzie cal wyjście posiada kolumny 3-znakowe; {3} może zostać zmieniony tak, aby pasował do twojego wyjścia cal.

+0

+1 Nie rozumiem ani słowa, czas na naukę nowej magii perl ;-) –

+0

Myślę, że 'cal -h | perl -F '(. {1,3}) "-ane" BEGIN {$, = "\ t &"; $ \ = "\ t \\\\\ n"} dalej, jeśli $. == 1; print @ F [3,5,7,9,11] ''jest bardzo dokładny i" solidny ". Zaktualizowane pytanie. –

1
cal 02 2012|perl -lnE'$.==1||eof||do{$,="\t&";$\="\t\\\\\n";$l=$_;print map{substr($l,$_*3,3)}(1..5)}' 

moje ulubione:

cal 02 2012|perl -F'(.{1,3})' -anE'BEGIN{$,="\t&";$\="\t\\\\\n"}$.==1||eof||do{$i//[email protected];[email protected][map{$_*2-1}(1..$i/2)]}' 
+0

To jest odpowiedź (chociaż tylko krótsza wersja mojej ;-)) –

+0

Tak, to jest modyfikacja twojej wersji. –

0

To może pracować dla Ciebie:

cal | sed '1d;2{h;s/./ /g;x};/^\s*$/b;G;s/\n/ /;s/^...\(.\{15\}\).*/\1/;s/.../ &\t\&/g;s/\&$/\\\\/' 
+0

dlaczego głosowanie w dół? nie widzę w tym nic złego. –

+1

@JohnRiselvato dzięki. – potong

Powiązane problemy