Befehlsreferenzen

Meine persönlichen Gedächtnisstützen der wichtigsten Werkzeuge ...


Top

bash


Reihenfolge
===========
  tilde-expansion
  variable-substitution
  command-substitution
  arithmetic expression
  word splitting of expanded text
  wildcard expansion
  command-lookup

eval ...  
printf "%10.10s\n" "$a" $b $c               # Quoting !
printf "%b\n" "Hello\nWorld"                # %b == %s mit Escape-Sequenzen
printf "%d\n" 011 0xff                      # oktal und hexadezimal
printf "%04d" 3                             # 0-Padding => 0003
printf "%-15s:\n" Hugo                      # flush left
printf "%Farbe: #%02x%02x%02x;\n" 66 43 171 # hexdezimal mit 0-Padding (%X ist Klein, %X Gross-Darstlelung)
printf "%10.2 f\n"                          # Laenge 10 inkl. Dezimaltrenner und 2 Nachkommastellen (!)
printf "%-10.5s:\n" Willibald               # 5 Zeichen mit Feldbreite 10 linksbuendig ausgeben => Willi    :
printf -v var "%04d" 5                      # 0005 => var
printf "%.5d\n" 5 => 00005
printf "%.4s\n" "string" => stri
printf "%${width}.${prec}f\n 14.7358
printf "%x %X" 15 15                        # f F

  Precision (Bedeutung)
  =====================
  printf "%.5d\n" 12345 => 123456           # keine Bedeutung, falls Zahl mehr Stellen als precision
  printf "%.5d\n" 5 => 00005                # falls Zahl weniger Stellen als precision: Ausgabe von precision Stellen mit 0-padding
  %s                                        # Maximalzahl an Zeichen
    %-5.4s                                  # 5 Stellen Feldbreite, maximal 4 Zeichen linksbuendig ausgeben
    %.4s                                    # maximal 4 Zeichen ausgeben
  %f                                        # Zahl Dezimalstellen
  Flags
  =====
  Space-Flag
    printf "% d\n" 15 -15                   # Positive Zahlen mit ' ', negative mit '-'
  0-Flag
    printf "%05d\n" 15                      # 0-Padding => 00015
  #-Flag                                    # Kennzeichnung von Oktal- und Hexadezimalzahlen
    printf "%x %#x" 15  15                  # => f 0xf
  
echo -n (kein Zeilenumbruch)
echo -e "Hello\nWorld\n"                    # Interpretation von Escape-Sequenzen
> file                                      # file leer anlegen/ueberschreiben
printf "%s Hugo\n" > file 2>&1
printf "%s Hugo\n" &> file                  # 1 und 2 umleiten (dito >&)
#-------------------------
exec 0<file                                 # dauerhafte Umleitung
exec 1>file                                 # dauerhafte Umleitung
  exec 5>&2                                 # Fehlerlausgabe (2) auf Ausgabe 5 "sichern"
  exec 2> /tmp/hugo                         # Fehlerausgabe aendern
  exec 2>&5                                 # Fehelerausgabe "zuruecksichern"
  exec 5>&-                                 # Sicherung loeschen
#-------------------------
read a b c d                                # $d beinhaltet Rest der commandline
date=$(date)                                # == date=`date`
[ ]                                         # == test (builtin command (strings, integers und Dateiattribute))
  [ "$var" -eq 0 ]
  [ "$str" != "string" ]
  [ -z "$str" ]
[[ ]]                                       # test inkl. regular expressions (not builtin command => parameter expansion ohne word spliting und file name expansion)
[[ "$hugo" = "string" ]]                    # Reiner String-Vergleich (da quoted right arguement)
[[ "$hugo" = pattern ]]                     # Cave: unquoted right argument => behandelt pattern analog "shopt -s extglob" wie auch case-statement, d.h. 
[[ "$string" == hugo@(willi|frank)theo ]]   # das pattern muss den Vergleichs-String VOLLSTAENDIG abdecken
[[ "$hugo" =~ h[ae]inz ]]                   # extended regular expression (Muster muss string NICHT vollstaendig abdecken) gemaess "man regex 3"
[[ "$hugo" =~ "h[ae]inz" ]]                 # Cave: Muster ist reiner String 'h[ae]einz' (keine extended regular expression), muss Vergleichs-String jedoch NICHT vollstaendig abdecken

while read line; do                         # cf. voriges Beispiel
  [[ "$line" =~ H[a-z]inz ]] && printf "Muster gefunden: %s\n" "$line"
  [[ "$line" =~ "H[a-z]inz" ]] && printf "String gefunden: %s\n" "$line"
done < <(echo -e "1. Heinz\n2. H[a-z]inz und Willi")

#----------------------------------------
# In while-condition mit mehreren 
# Bedingungen 
#   falls auf einer Zeile => durch ';'
#   zu trennen
# ist nur deren letzte
# als Schleifenbedingung massgeblich
# while <list>; do
#   <list>
# done
# 
# Eine Zuweisung vor der Schleifen-
# bedingung auf derselben Zeile 
# muss NICHT durch ';' # getrennt werden
#----------------------------------------
declare -i i=0 max=10
while (( i++ )); [ "$i" -lt "$max" ]; do    # Nur letzte Anweidung ist Schleifenbedingung
  echo "i: $i ($max)"
done

while IFS=':' read line; do                 # kein ';' zwischen Zuweisung und Bedingung
 ...
done
#----------------------------------------   # read in eine Variable trimmt leading und trailing whitespace
while read var; do
  printf "%s\n" $var
done < <(cat << EOF
  Hugo   Willi   Franz      
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^               # <= Whitespace
EOF
)

=>

Hugo   Willi   Franz
^^^^^^^^^^^^^^^^^^^^                        # kein Whitespace
#----------------------------------------
tr -s ' ' ' ' < file                        # '-s' ersetzt eine "sequence" des Folgezeichens in Eingabe => Kompression von Blanks
#----------------------------------------

test $(( a - 2 )) -ne 0                     # Arithmetik: Variablen muessen nicht dereferenziert werden
if (( total > max )); then                  # da kein builtin sondern shell-syntax, werden '<>' nicht als redirection interpretiert
(( var )) && ...                            # Test auf non-zero
Listen:                                     # Exit-code = Exit-code des letzten statements
  <command>;<command>;...
  <command> && <command> ...
  <command> <newline>
  <command>
case-statement                              # Pattern analog pathname-expansion mit wildcards, character lists und ranges 
  case $1 in                                # Substring-Test (schnell)
    *"$2"*) true ;;
         *) false ;;
  esac
  case $1 in                                # Integer-Test
    *[!0-9]*) false ;;
           *) true ;;
  esac
break 2                                     # zweite Schleife von innen verlassen
printf "%s" "$@"                            # Einzel-Quoting aller Parameter
printf "%s" $@                              # Word-Splitting
printf "%s" "$*"                            # Gesamt-Quoting des Parameter-String
{01..10..2}
{a..z..2}
a*b?[[:lower:]][h-o]                        # Pathname-Expansion (unquoted ?*[] treated as file globbing parameters)
[[:upper:]][[:lower:]]                      # Gross-, gefolgt von Kleinbuchstabe
#-------------------
while read file; do
  ...
done < <(ls *.jpg)                          # Process substitution
#-------------------
while getopts "hx:" opt;do
  case $opt in
    h) puts "help" ; exit;;
    x) var="$OPTARG" ;;
  esac
done
#-------------------
Subshell ()                                 # erzeugt neuen Prozess
  $(...)                                    # command substitution
  | ...                                     # pipelines
  ( <command> )                             # Befehle in '()'
  prog() (....)                             # Funktion in Subshell

  tar -cf - . | (cd /newdir; tar -xpf -)    # tar aktuellen Verzeichnisses => stdout | subshell: cd und tar-Extraktion von stdin
                                            # Cave: Da Subshell kein Verzeichniswechsel für Haupt-Shell !
Code-Block {}                               # kein neuer Prozess <=> Subshell
  cd dir || {
    ...
  }

Parameter Expansion
===================
${var:-alternative}                         # falls var nicht gesetzt oder leer => alternative
${var-alternative}                          # falls var nicht gesetzt           => alternative
${var:=default}                             # ggf. Zuweisung
${var:+default}                             # falls var gesetzt und nicht leer  => default
for token in a b c; do
  var="${var:+"$var "}$token"
done
${var:?Variable ist leer}                   # Fehlermeldung
${#var}                                     # Laenge der Variablen
${var%.*}                                   # Endung beschneiden
${file##*/}                                 # Pfad abschneiden
printf "%s\n" ${passwd//?/*}                # Passwort verschleiern
printf "%s\n" ${passwd/[[:upper:]]/*}       # Ersetzung des ersten Grossbuchstabens
${var:2:2}                                  # offset und length
#---------------------------------          # dito fuer Arrays (offset bezeichnet Element mit diesem Offset, length die Anzahl Elemente ab diesem)
array = (one two three four)
${array[@]:1}                               # two
${array[@]:1:2}                             # two three
#---------------------------------
${!var}                                     # Dereferenzierung
${var^^}
${var^[h-k]}                                # Erstes Zeichen gross schreiben, sofern im Bereich h-k
${var,,[A-F]}                               # Alle Zeichen klein schreiben, sofern im Bereich A-F
$#                                          # number of positional parameters
#---------------------------------
array=( fifi lala huhu )
printf "%s\n" "${array[@]/%fi/bu}"          # Ersetzt in allen Elementen eine Nachsilbe fi => fibu lala huhu
printf "%s\n" "${array[@]//fi/}"            # Loescht in allen Elementen jeweils alle Vorkommen von "fi" => lala huhu
printf "%s\n" "${array[@]/%[iau]/}"         # Loescht in allen Elementen jeweils ein endstaendiges i,a oder u => fif lal huh
printf "%s\n" "${array[@]^^}"               # Konvertiert alle Elemente zu Uppercase
#---------------------------------
declare -A arr
#---------------------------------
for i in "${!assoc[@]}"                     # ${!assoc[@]}  <= Keys
do                                          # ${assoc[@]}   <= Values
  echo "key  : $i"
  echo "value: ${assoc[$i]}"
done
#---------------------------------
arr=( a b c )
arr+=( d )
${arr[0]}
printf "%s\n" "${arr[*]}"                   # quoted "*" => ein String
printf "%s\n" "${arr[@]}"                   # quoted "@" => jeder Parameter wird ein String
printf "%s\n" ${arr[@]}                     # unquoted @ (oder *) => Word Splitting ueber alle Parameter
printf "%s\n" "${arr[@]:1:2"                # Zweites und drittes Array-Element jeweils ohne Word-Split ausgeben
printf "%s\n" "${#arr[*]}"                  # Laenge des Arrays (* oder @)
printf "%s\n" "${#arr[2]}"                  # Laenge des dritten Elementes
case var in
  "" | *[!0-9.]* | *[!0-9]) ;;              # Leer oder (Nicht Zahl oder Punkt) oder keine Zahl am Ende
esac                                        # Cave: var muss vollstaendig durch Muster abgedeckt sein
set -- $2 $3 $1                             # Resortierung '--' beendet Optionsliste fuer set
set -- $name $dial $address
set -a                                      # '-'Kurzoption setzt eine Funktion (hier: Export aller folgenden Shell-Variablen)
set +a                                      # '+' == unset einer Funktion
set -o allexport                            # Langform des Exports folgender Shell-Variablen mit Option -o
set +o allexport                            # '+' == unset
set -x                                      # print commands after expansion before running them
set -v                                      # print commands verbatim
set -o vi                                   # vi-style behavior
result="$( ls )"                            # schlecht: Ausgabe durch command substitution variable zuweisen
usage(){
  printf "%s\n" ${var:-Kein Wert}
} > ${1:-/dev/filedescriptor}
declare -n name=${var:-Leer}                # Namensreferenz => name ist var
var+="a b c"                                # Konkatenierung (analog bei Array: arr=( a b ) arr+=( c d )
var=${var:0:$limit}
printf -v result "%c" "$var"                # Zuweisung des ersten Zeichens aus var an Variable result

tmp=${var#?}                                # erstes Zeichen abschneiden =>
res=${var%"$tmp"}                           # alles bis auf das erste Zeichen abschneiden
echo var | tr 'a-z' 'A-Z'

case var in
  y|Y) ... ;;
  [aA] ... ;;
esac

substr=${string:0:$(( $end - 2))}
rightspaces=${var##*[! ]}                   # Alles bis auf letzten Whitespace rechts abschneiden
leftspaces=${var%%[! ]*}                    # Alles vom ersten Non-Whitespace bis zum Ende abschneiden
#-------------------------
while read; do                              # => $REPLY
  ...
done < file
#-------------------------
while read a b c; do                        # c erhaelt Rest jeder eingelesenen Zeile
  ...
done < file
#-------------------------
while IFS=";" read surname prename          # Eine Zuweisung vor einem Befehl macht die Variable lokal bezueglich des Befehles
  ...                                       # Cave: Zuweisung vor builtin bleibt auch nach Beendigung des builtin gueltig
done < file
#-------------------------
cat a.txt | tr 'aeiou' 'AEIOU' > out.txt
#-------------------------
{                                           # Gruppierung (nicht Sub-Shell)
  date
  cat report.txt
} | mail -s "Hugo" name@adress
#-------------------------
{                                           # Gruppierung mit Umleitung der Standardausgabe
  while IFS=":" read team lead rest; do     # Cave: IFS gilt hier nur fuer read !
    printf "%s\n" "$dashLine"
    printf "%30.30s: %-40.40s %s\n\n" "$team" "" "$lead"
    printf "%30.30s: %-40.40s %s\n\n" "Scope-ID" "Anteil" "Scope"
    IFS=":"
    read -a claimArr <<< "$rest"            # Zerlegung von $rest als Here-String
    for claim in "${claimArr[@]}"; do
      scopeId=${claim%|*}
      anteil=${claim#*|}
      printf "%30.30s: %-40.40s %s\n" "$scopeId" "$anteil" "${scopeHash[$scopeId]}"
    done
    IFS=" "
  done < $teamfile
} > $outfile
#-------------------------
cat "$@" | while IFS=";" read line; do 
  ... 
done                                        # Mehrere Dateien einlesen
#-------------------------
while IFS=";" read line; do
  ...
done < <(cat "$@")                          # dito via process-substitution
#-------------------------
IFS=";" read a b c d < $file                # Erste Zeile einlesen (Zuweisung vor command bewirkt Lokalitaet)
#-------------------------
{
  read line1
  read line2
} < $file
#-------------------------
for i in {1..4}; do
  read lines[${#lines[@]}]                  # ziemlich abgehoben (Index ist immer die aktuelle Zahl von Elementen des Array)
done < $file
#-------------------------
mapfile -t -n 4 lines < $file            # n 4 (4 Zeilen einlesen) t (trailing newline entfernen)
printf "%s\n" "${lines[@]}"
#-------------------------
read -a array -p "Bitte Werte eingeben"
printf "%s\n" "${array[@]}"
#-------------------------
for file in {a..z}$RANDOM; do               # besser als touch ...
  > $file
done
#-------------------------
cut -c 22-24 $file | head -n3
cut -d : -f 1,5 /etc/passwd
#-------------------------
names="Willi,Franz,Hugo"
IFS=","
arr=( $names )
printf "%s\n" ${arr[2]}                     # => Hugo
#-------------------------
set -- $var                                 # Word-Split => $1,$2,$3, ...
#-------------------------
Regex                                       # im unterschied zu file expansion
=====
.                                           # jedes Zeichen
*                                           # 0 oder beliebig viele des vorigen Zeichens
File expansion                              
==============
*                                           # matched keine dot-files
.*                                          # matched dot-files
#-------------------------
printf "%s\n" {1..10} | 
awk '
  { total+=1 ; }
  END { print total; }
'
#-------------------------
shopt -s extglob
  ?(heinz|franz)                            # ein oder kein
  *(heinz|franz)                            # kein oder beliebige
  +(heinz|franz)                            # ein oder beliebige
  @(heinz|franz)                            # entweder oder
  !([abc0-9]*)                              # weder noch (Cave: Muss im Gegensatz der vorigen (logischerweise) den gesamten Vergleichs-String abdecken !)
                                            # Cave: '*' ist hier beliebige Zeichenfolge (globbing), nicht "0 oder mehrere" (regex)
  ---- Beispiel -----
  shopt -s extglob

  for string in "abc" "bbc" "cbc" "dbc"; do
    case $string in
      !([ab]*)) printf "%s did not match a or b at beginning\n" "$string" ;;
             *) printf "%s did match a or b at beginning\n" "$string" ;;
    esac
  done

time <command>                              # Messung der Ausfuehrungszeit
#-------------------------
printf "%s\n" "hugo" "willi" | {            # common subshell
  <command>
  <command>
}
read -r                                     # backslash literally einlesen
#-------------------------
rest="hugo:willi:franz"
IFS=":"
read -a array <<< "$rest"
printf "Array-Element: %s\n" "${array[@]}"
#-------------------------
printf "%s " "a" "b" | {
  read -a arr                               # Array einlesen
  printf "%s\n" ${arr[1]}
}
#-------------------------
read -n 1 var                               # nur 1 Zeichen einlesen
read -s var                                 # Ausgabe der Eingabe unterdruecken (Passworte)
read -p "Eingabe: " var                     # Eingabeaufforderung
read -p "Weiter ? (j/n): " -s -n 1 var
read -t 2  var                              # Timeout 2 Sekunden
#-------------------------
set -x                                      # Ausgabe der Verarbeitungsschritte
#-------------------------
eval "$(date "+year=%Y" month=%m day=%d")"  # funktioniert, da in date-Formatstring jeder Zusatztext erlaubt ist
#-------------------------
{
  echo "a"
  echo "b"
} > file                                    # gemeinsame Umleitung
#-------------------------
join file1 file2                            # Spaltenweise Zusammenfassung anhand gemeinsamen "Primaerschlussels"
#-------------------------
format -s ...                               # split long lines
format -w 60 ...                            # wrap bei 60 Spalten
#-------------------------
Druck
  lpr
  lpstat
  lpq
  lprm
  lpoptions
#-------------------------
export -p                                   # Ausgabe der Umgebung
#-------------------------
if [ -n "$a" -o -n "$b" ]                   # -a und -o sind Test-Operatoren
if [-n "$a" ] || [ -n "$b" ]                # || und && jedoch sind Shell-Operatoren
#-------------------------
cat << "EOF"                                # quoted => keine Variablen-Substitution
  $a                                        # $a wird nicht substituiert
EOF
#-------------------------
# falls noexpandtab gesetzt ist
cat <<-ENDE
       Hugo
       Willi
       ENDE
#-------------------------
for file in $(cd /dir; echo *.txt); do      # command-substitution
  diff /old/dir/$file $file
done | more

Fortgeschrittene Beispiele
==========================

${vec[@]^^[aeiou]} 
${vec[@]//[aeiou]}

string=franz_hugo_willi
[[ $string =~ (fritz|h(ug|ag)o)_willi ]]    # extended regular expression (man regex 3)
echo ${BASH_REMATCH[@]

string=aabbbbycc
[[ $string =~ a{2}b{2,3}[xyz]c{1,2} ]]

for element in a b c d e; do
  list=${list:+$list,}$element
done

birke=baum
arr=(birke fichte tanne)
declare -A assoc=([heinz]=breinlinger [ingrid]=daubechies)
${arr[@]^[ft]}
${arr[@]/fich}
${arr[@]//e/E}
${!arr[0]^^}
${assoc[@]^[td]}

# falls noexpandtab gesetzt ist
shopt -s extglob
set -x 
mapfile -t <<- ENDE
	Hugo1 Hugo2
	Willi1 Willi2
	ENDE
printf "%s\n" "${MAPFILE[@]}"                    # zeilenweise Ausgabe, da quoted
printf "%s\n" ${MAPFILE[@]}                      # wortweise Ausgabe, da unquoted
IFS="|"
read -a array <<- ENDE
	Hugo|Willi|Franz
	ENDE
printf "%s\n" "${array[@]}"                      # geaenderter internal field separator

------------------------------------------------------------------------------------------
cat <<EOF
  $Hugo
EOF
------------------------------------------------------------------------------------------
cat <<'EOF'                                      # keine Ersetzungen
  $Hugo
EOF
------------------------------------------------------------------------------------------
cat <<-EOF                       
      $Hugo                                      # Tab-Unterdrueckung
EOF
------------------------------------------------------------------------------------------
myfunction <<EOF                                 # Funktionsaufruf mit 2 Parametern
  param1
  param2
EOF
------------------------------------------------------------------------------------------
: <<'DISABLED'                                   # Pogramm-Code auskommentieren
  command
  command
DISABLED
------------------------------------------------------------------------------------------
command <<< $var                                 # Here-String => stdin fuer command

  cat <<< $var
  cat <<< 'Escaped variable $var'                # keine Ersetzungen

Top

vim

Zwischen Operator-Command und Move-Command ist Operator-Pending-Mode

=====================================
{command}{number} {text-object == movement-command}
{number}{command} {text-object == movement-command}

In ex-Mode wird Text mit Zeilenadressen bestimmt, in vi-Mode mit Text-Objekten/Movements


- Kleinbefehle
    Ctrl-f,Ctrl-b,Ctrl-u,Ctrl-d (ganze, halbe Seite nach unten/oben)
    Ctrl-y,Ctrl-e  (1 Zeile weiter nach unten/oben)
    {,} next, previous paragraph
    z
    z.
    z-
    a,i,A,I,o,O
      10i-<ESC> (fuegt 10 '-' ein)
    H,M,L Cursor nach oben, Mitte, unten
      10H (10 Zeilen unterhalb Oberkante)
      5L  (5 Zeilen oberhalb Unterkante)
    h,10j,5k,3l
    g0
    d/Hugo  (Loesche bis Hugo)
    c/Willi (Aendere bis Willi)
    y/Franz (Kopiere bis Franz)
    d- (Loesche bis Anfang der vorherigen Zeile)
    cG (Aendere bis Dateiende)
    dH (Loesche bis Oberkante Bildschirm)
    cn (Aendere bis zum naechten gefundenen Muster)
    "2p (2. Loeschung (in Buffer 2) rueckgaengig machen)
    "a7yy (7 Zeilen in Buffer a)
    "aP   (vor Cursor Buffer a einfuegen)
    "Ay)  (Bis Satzende an Buffer a anhaengen)
    G (Dateiende)
    4G (Gehe zu Zeile 4)
    % (Klammerpaare)
    0,$
    3yb oder y3b (3 Worte zurueck kopieren)
    5yl (5 Zeichen zurueck kopieren)
    gj,gk,g0,g$
    Ctrl-g (Dateistatus)
    "ayw
    "ap
    r,R
      10r- (ersetzt 10 Zeichen durch '-')
      Vr-  (ersetzt in visuell markierter Zeile alle Zeichen durch '-')
    yl Kopiere aktuelles Zeichen  
    y$ alles bis Zeilenende kopieren
    y0 dito bis Zeilenanfang und vor aktuellem Zeichen
    s == cl
      Ersetzt EIN Zeichen mit beliebig viel Text
      7s (ersetzt 7 Zeichen und entspricht daher praktisch R)
    d2w,d3h
    db
    d/letztes_Wort  (move ist ein Pattern)
    g modifiziert Folgebefehl
    gUiW
    gue
    gUge (Grosschreibung zurueck bis Ende des letzten Wortes)
    - undo
      Chunks werden mit jedem Wechsel von Normal- zu Insert-Mode festgelegt
      (zusaetzlich auch durch Pfeiltasten bei Navigation)
      u (undo)
      U (Undo gesamte Zeile, solange Cursor auf Zeile bleibt)
      Ctrl-r (redo)
    g~ Case-Wechsel
    ~ Case-Wechsel
    30~ Case-Wechsel der naechsten 30 Zeichen
    > oder < oder =
    gR (virtual replace mode => Tab als Folge von Blanks interpretieren)
    Ctrl-o und Ctrl-i (zwischen letzten Sprungmarken vor- und zuruecknavigieren)
    "ac2w (naechste 2 Worte aendern und Original in Register a)
    Visual Mode
      zeichenweise
        v
          viw
          vaW
      zeilenweise
        V
      spaltenweise
        Ctrl-v
          Aenderungen fuer weitere Zeilen werden nach <Esc> uebernommen
      o (springt an anderes Markierungs-Ende)
      Ctrl-g (toggled zwischen Visual- und Select-Mode (direktes Ueberschreiben analog Windows))
      Vr- (ersetzt jedes Zeichen der Auswahl mit '-')
    Insert-Mode
      Ctrl-d (Auszug)
      Ctrl-t (Einzug)
      Ctrl-h (Zeichen loeschen)
      Ctrl-w (Wort zurueck loeschen)
      Ctrl-u (Bis Zeilenanfang loeschen)
      Ctrl-o (Wechsel zu Insert-Normal-Mode: Ein Schuss in Normal-Mode)
      Ctrl-r 0 Register 0 ausgeben
      Ctrl-r Ctrl-p 0 (dito, jedoch ohne Einrueckungen)
      Ctrl-= 20 * 5 (Rechenergebnis einfuegen)
      Ctrl-v (Zeichen woertlich eingeben)
      Ctrl-v 065 (ga zeigt Codierung des aktuellen Zeichens an)
      Ctrl-v <Tab> (Tabulator ohne Expansion eingeben)
      Ctrl-v u{1234}
      Ctrl-k Digraph-Code (:digraph)

- Doppelbefehle sind Shortcuts und beziehen sich auf die aktuelle Zeile
    cc
    >>
    dd
    yy
    gUgU (oder gUU)

    xp (Tausch zweier Zeichen => "transpose" als Merkhilfe)
- Großbefehle sind ebenfalls Shortcuts und beziehen sich auf den Rest der Zeile oder die ganze Zeile
    C (Rest der Zeile) == c$
    D (Rest der Zeile) == d$
    Y (bezieht sich auf ganze Zeile)
    S (bezieht sich auf ganze Zeile) == ^C
      10S (substituiert 10 Zeilen)
    4J (4 Zeilen verbinden)
- Text-Objekte (i hier analog a: a(round) oder i(inside) )
  aW
  ap
  a) == ab
  a} == aB
  a]
  a>
  a'
  a"
  at (Tag)
- Suchen/Finden
    /,?
    /Burg
    /~en (Tilde ist letzter Suchausdruck) => /Burgen
    f,F,t,T
    10,20g/Hugo/s/Franz/Willi/g
    *,# (Wort unter Cursor vorwaerts oder rueckwaerts)
    :set ignorecase
    :set smartcase
    /foo\C  case-sensitive search
    /Foo\c  case-insensitive search
    /Hugo/c (confirm)
      y,n,q(uit),l(ast),a(ll)
      Ctrl-e Bildschirm nach oben
      Ctrl-y Bildschirm nach unten
    Posix-Character-Classes
      [:alnum:],[:alpha:],[:blank:] (space und tab),[:digit:],[:space:] (Whitespace),[:lower:],[:upper:]
- Sessions
    :mksession ~/Downloads/Sitzung.txt
    vim -S ~/Downloads/Sitzung.txt
- Macro
    qa (in Register a speichern)
    qA (an Makro in Register a anhaengen)
    q
      => qaq (Register a loeschen)
    @a
    4@a
    @@
    '<,'>normal @a
- Command-Line-History
    q:
- Search-History
    q/
- Filterung in vi-Mode
  ====================
  Cave: 
    2 Formen
      !<number><movement><command>
      <number>!<movement><command>
    Movement-Command nach '!' muss mehrere Zeilen umfassen und bezieht sich auf alle Zeilen von Anfang bis Ende der jeweilgen Zeile
      also nur moeglich: (),G,{},[],+,-
      Beispiel
        !10+ (naechste 10 Zeilen)
        10!+ (naechste 10 Zeilen)
    !! ist Abkuerzung fuer aktuelle Zeile
  !) <command> (bis ans naechste Satzende durch <command> filtern)
- Command-Line
    :set (no)wrap(margin)
    :set (no)number
    :set (no)hls Toggle Syntax-Highlighting-Suche
    :syntax on|off (Syntax-Highlighting)
    :shell
    Ctrl-f (Command-Line Window)
    Ctrl-z (Stop und Shell aufrufen => Beenden/Rueckkehr mit fg)
      :! ls
      :!r(ead) ls
      :$!uptime (letzte Zeile durch Laufzeit ersetzen)
      :10,20! sort -t',' -k2
    :source hugo.vim (wenn hugo.vim ex-Befehle enthaelt)
    :buffers
    :w >> bestehende_Datei
    :w %.new
    Auch Datei-uebergreifend kopieren
      10,20yank a
      <Datei-Wechsel>
      "ap
    :bnext,bprevious,bfirst,blast,bdelete (Nummer oder Name)
      :3,5 bdelete
    :n(ext) (naechste Datei editieren)
    :1,10# (Zeilennummer temporaer einblenden)
    :args
    :args a,b,c (befuellt die Argument-Liste <=> Buffer-Liste jedoch davon unbeeinflusst)
    :argdo,qa(ll)!,wa(ll)!
    :e(dit)! Datei neu einlesen (== Aenderungen verwerfen)
    :e Hugo.txt (weitere Datei editieren)
      % ist aktuelle Datei
      # ist alternative Datei
    :r# Zweite Datei in erste einlesen
    :Explore,Vexplore,Sexplore,edit
      :Explore ~/Downloads
    :browse open
    :col Ctrl-d (Liste der Moeglichkeiten mit col...)
    :col <tab> (schrittweise durch Liste der Moeglichkeiten mit col...)
    :colorscheme Ctrl-d (Anzeige der Farbschemata)
    :Ctrl-r Ctrl-w (uebernimmt Wort unter Cursor auf Kommandozeile)
    :ls
       % ist aktueller Buffer
       # ist alternativer Buffer
    :tabnew,tabnext,tabprevious,tabmove N,tabclose,tabonly
    :registers
    :10 (gehe zu Zeile 10)
    :10,20t.
    :1,7y
    :2,9p
    :.,/while/d (von aktueller Zeile bis Zeile mit Muster 'while' loeschen)
    :%y Alle Zeilen kopieren
    :100;+5p   (';' bewirkt relative Adressierung zu Anfangszeile, bzw. Anfangszeile wird zu aktueller Zeile => identisch zu 100,105p)
    :3,8j
    :10,20co17
    :10,20m.
    :17,19d
    :5,25 normal 2WA; (2 Worte nach rechts; am Zeilenende ';')
    :%normal yi"$p  (Kopiere in allen Zeilen innerhalb '"' und gib an Dateiende aus)
    :% normal i//
    :5,25g/Hugo/normal @a  (Macro aus Register a auf Zeilen von 5-25, welche Hugo beinhalten)
    :v(global)/href/delte (reziprokes global)
    :%s/Hugo/Willi/g
    :/<Start>/+1,/<End>/-1d
    :'<,'>   Range bei visueller Auswahl 
    :.,.+3p
    :'ms/Hugo/Willi/g  Range mit Markierung 'm'
    :5co0  (0 ist virtuelle Zeile oberhalb Datei)
    :'<'>t0
    :t. (Duplizierung)
    :%s/\v ...  (very magic == nur Buchstaben, Zahlen und '_' ohne Sonderbedeutung)
      Beispiel

      30.09.2021

      :2,41s/\v([0-9]{2})\.([0-9]{2}).([0-9]{4})/\3-\2-\1/

      =>

      2021-09-30

    :10mark a
    :10;+10w >> Hugo.txt (Zeilen 10-20 an Hugo.txt anhaengen)
    :17r Hugo.txt (Hugo.txt nach Zeile 17 einlesen)
    :/Markierung/r Hugo.txt (Hugo.txt nach Zeile mit Muster "Markierung" einlesen)
    :%s/Hugo/"\1"/g
    :%s/\V ...  (very non-magic)
    :%s//Willi nutzt letzes Suchmuster fuer Ersetzung
    :%s//<Ctrl-r 0>/g  letztes Suchmuster durch Inhalt des Registers 0 ueberall auf allen Zeilen ersetzen
    :%s//\=@a/g  dito, jedoch mit Macro aus Register a
    :%s//~/g letztes Suchmuster durch letztes Ersetzungsmuster auf allen Zeilen ueberall ersetzen
    :g//d  Alle Zeilen mit letztem Suchmuster loeschen
    :g/muster/.w >> Muster.txt Alle Zeilen mit Muster in Datei Muster.txt schreiben
    :g/Hugo/s/\(Willi\|Franz\)/"\1"/g  Auf allen Zeilen mit Hugo alle Vorkommen von Willi oder Franz in '"' setzen
    :g/\vHugo/s/(Willi|Franz)/"\1"/g   very-magic: Auf allen Zeilen mit Hugo alle Vorkommen von Willi oder Franz in '"' setzen
    :g/\vHugo/s/(Willi|Fr%(a|e)nz)/"\1"/g   very-magic: Auf allen Zeilen mit Hugo alle Vorkommen von Willi oder Franz oder Frenz in '"' setzen, dabei Klammer mit %(a|e) nicht zaehlen
    :v//d  invers zu vorigem
    :g!//d analog :v//d
    :g/ToDo/yank A (Alle Zeilen mit ToDo in Register a verketten)
    :g/ToDo/t$ (Alle Zeilen mit ToDo ans Dateiende kopieren) 
    :g/{/ .+1,/}/-1 sort   (Cave: Blank nach erstem Suchmuster: Abschnitte zwischen '{}' sortieren)
    :s/\v:[^:]+:/[&]/g     (very-magic: Alle in ':' eingeschlossenen Worte in '[]' einschliessen)
    :g/Syntax/.,/Syntax-Ende/-1 move /Parameters/-1 
      entspricht Muster :[range]g(lobal)/Pattern/ Command
          Pattern: /Syntax/
          Befehl:  .,/Syntax-Ende/-1 move /Parameters/-1
        Finde Zeilen mit /Syntax/ 
        Implizit: Setze Zeile als aktuelle Zeile '.'
        von dort bis Zeile vor Zeile mit /Syntax-Ende/
        verschiebe vor Zeile mit /Parameters/
    :g/>stream/ .+1,/endstream/-1 delete                     # Loeschen von Stream-Inhalten in PDF-Datei
    :g/Chapter/ .+2w >> Hugo.txt (Haenge die jeweils 2-te Zeile nach Zeile mit "Chapter" an Datei Hugo.txt)
      Zeile mit Muster wird implizit aktuelle Zeile '.'
    :/Anfang/,/Ende/g/Chapter/ .+2w >> Hugo.txt (Haenge die jeweils 2-te Zeile nach Zeile mit "Chapter" innerhalb des Ranges Anfang-Ende an Datei Hugo.txt)
    :/Anfang/,/Ende/g/Chapter/ .+2w >> Hugo.txt | .+1t$ (dito und kopiere die Folgezeile (also dritte Zeile nach Chapter-Zeile) ans Dateiende)
      vor '|' ist aktuelle Zeile die zweite Zeile nach Chapter-Zeile
    :g/Description/,/Parameters/-1d Alle Abschnitte von Description bis Zeile vor Parameters loeschen
    :g/.*/mo 0 (Zeilenfolge umdrehen)
    :g/^/mo 0  (Zeilenfolge umdrehen)
    :v/\v^[[:digit:]]+/mo $  very-magic: Alle Zeilen, welche nicht mit einer Zahl beginnen, ans Dateiende verschieben
    :g/\v^[^[:digit:]]/mo $  very-magic: Alle Zeilen, welche nicht mit einer Ziffer beginnen, ans Dateiende verschieben

    Wiederholung von Befehlen mit g: (Learning the vi and vim editors)
    ================================
      Hintergrund: :[range]g(lobal){Muster}{Befehl} 
        Befehl muss sich nicht auf Trefferzeilen mit Muster beziehen !
      :1,10g/^/ 20,27co $ (Kopiere Zeilen 20-27 10 mal ans Dateiende)
- Muster
    <, > Word-Boundaries (zero-width-items)
    \_ vorangestellt bedeutet "inkl. Zeilenende"
      \_s+  (Whitespace inkl. Zeilenende)
    /\v<(\w+)\_s+\1>  very-magic-Suche nach doppelten Worten, durch Whitespace oder Zeilenende getrennt
    :s entspricht :s//~/  (letztes Suchmuster und letzter Ersetzungs-String)
    :s;/home/heinz;/home/anja;g  # ';' als Delimiter anstelle '/'
    Einfuegungen des substitute-commands (Replacement-String)
      \1 \2 \0 (gesamter Treffer)
        :10,20s/\v(that) or (this)/\u\2 or \u\1/g => This or That
      \t \r 
      & == \0 (gesamter Treffer)
        :%s/\v[[:alnum:]]+/\u&/g => very-magic: Kapitalisierung aller Wortanfaenge
        :%s/\v[[:alnum:]]+/\U&/g => very-magic: Kapitalisierung aller Worte
        :10,20s/.*/(&)/
      ~ vorheriges Ersetzungsmuster, d.h. Ersetzung durch Ersetzungs-String des vorherigen (!) Ersetzungsbefehls
        :s/her/their/g
        :s/his/~/g
      \= Ersetzung durch VIM-Script-Ausdruck
    %(..) zaehlt Klammer nicht mit fuer Back-References
      :%s/\v(%(And|D)rew) (Neill)/\2, \1/g  Vor- und Nachname vertauschen, wobei die innere Klammer nicht gezaehlt wird ('%' vorangestellt)
    Look-Ahead und -Behind
      /\v"zs[^"]+\ze/  Suche nach Nicht-Anfuehrungszeichen innerhalb von '"' (zs: zero-start == look-behind   ze: zero-end == look-after)
- Fenster
  :set mouse=a (erlaubt Fensterunterteilungen per Maus zu aendern und Fenste per Maus zu aktivieren)
  :split,vsplit <Datei>
  Ctrl-ws (== split)
  Ctrl-wv (== vsplit)
  Ctrl-w Ctrl-w
  Ctrl-w(hjkl)
  Ctrl-w <Pfeil>
  Groesse aendern
    Ctrl-w= (gleiche Hoehen und Breiten)
    Hoehe
      10 Ctrl-w (AUF Groesse 10 setzen)
      10 Ctrl-w - 
      20 Ctrl-w + 
      :res -10
      :res +10
      :res 10 (Hoehe AUF 10 setzen)
    Breite
      10 Ctrl-w | (AUF Breite 10 setzen)
      10 Ctrl-w <
      15 Ctrl-w >
      :vertical res 10
      :vertical res -10
      :vertical res +10

  :close (Ctrl-wc)
  :only (Ctrl-wo)
  10 Ctrl-w (Hoehe 10)
  10 Ctrl-w| (Breite 10)
  :help window-moving
  :help window-resize
- Navigation
    w,e,E,W,ge,b,B
    iw,it,i",i{,ip
      dito mit aw,at, ...
    - z.B. daw, ciW
    +,- (Zu Anfang der naechsten, vorherigen Zeile)
    (,) (Anfang, Ende des aktuellen Satzes)
    {,} (Anfang, Ende des aktuellen Paragraphen)
- Arithmetik
   10 Ctrl-A
   20 Ctrl-X
   set nrformats-=octal (um aus 007 008 oder 006 zu machen; ist bereits Default)
- Register
    :register /    (Suchmusterregister anzeigen lassen)
    a-z ueberschreiben
    A-Z anhaengen
    _ (Black-Hole)
    " unnamed register (Default)
    = expression register
    : Letztes ex-command
    % aktuelle Datei
    # alternative Datei
    / letzes Suchmuster
    Ctrl-ra (Register a auf Command-Line einfuegen)
    Ctrl-r= 10 * 20 (Berechnungsergebnis einfuegen
    * (Middle-Mouse-Clipboard) und 
    + (Clipboard)
      :set noautoindent (empfohlen)
    "*yW Rest-Wort in Clipboard
    "*yaW Gesamt-Wort in Clipboard
    "*p Clipboard ausgeben


Top

sc

Cave: Jede Zelle kann gleichzeitig sowohl ein Label/einen String ALS 
      auch einen numerischen Wert enthalten. In alle Zellen koennen
      "parallel" Strings und numerische Werte eingegeben werden.
      
      Dies ist wichtig bei @ext(se,e), 
      da 'e' (expression) ein numerischer Wert sein muss, welcher als Argument 
      fuer den Aufruf von 'se' (string expression == command-line) in einen 
      String gewandelt wird. Nicht moeglich ist daher, fuer 'e' auf den 
      Label-Teil einer Zelle zu verweisen !

Cave: In *.sc Dateien stehen die Kommandos fuer Zellen in der eigentlichen (Lang-)Form.
      Diese Form ist zu verwenden fuer
        Macros
          => *.sc-Dateien koennen als Macro-Dateien-/Vorlagen genutzt werden
          cf. die (nur in der Man-Page dokumentierten) Befehle
            R(un)
            A(utoexecute)
            D(efine)
        Definition von Funktionstasten <F2>, <F3>, ...
      Die in einer sc-Sitzung eingegeben Kurzformen sind Shortcuts, welche
      in den Eingabemodus wechseln und in diesen (transparent) die eigentliche Langform eingeben
        cf. Man-Page
          the single key commands are shortcuts which switch to input mode after first entering the beginning of the full command for you

Command-Line
============
Cave: -P behaelt Formatierungen NICHT bei
  sc -P A0:G20/A30 Datei.sc > Auszug_verschoben.sc
    Kopiert Range A0 bis G20 in neue Datei, jedoch beginnend in Feld A30 (cf. unten)
  sc -v -P A0:M126 Datei.sc > Auszug_nur_mit_Werten.sc
    Kopiert Range A0 bis M126 und wandelt dabei alle Ausdruecke/Formeln in Werte 
sc -W A0:M126 Datei.sc > Bilschirm-Abbild.txt
  Erzeugt reine Textausgabe des angegebenen Ranges wie in sc-Sitzung auf dem Bildschirm dargestellt (also mit dortiger Formatierung)


Befehle
=======

<F1>  man sc
      cf. auch 
        fkey n = "command"

G(et database from file) <= aktuelle Datei wird ueberschrieben
M(erge database into current file)
  M /home/heinz/.scrc 
    laedt diese Datei hinzu
      Tipp: Vorher Ausschnitt und neuen Startpunkt der neu zu ladenden Datei festlegen mit
        sc -P A0:G50/A101 Datei_2.sc > Datei_2_Ausschnitt.sc
          Editieren und Zeielnbreiten (ggf. auch Farben) anpassen
        In Datei_1 (welche auf Zeile 99, also 2 Zeilen ueber dem neuen Startpunkt der Ausschnittdatei endet):
          M Datei_2_Ausschnitt.sc
$K$20 
  Zellangabe fix
P <Datei> Speichern
ZZ Speichern und verlassen
W <Datei> Speichern des Bildschirmabbildes
T CSV speichern mit ':'-Delimiter
.\scrc: Konfigurationsdatei
  Definition der Default-Dateiendungen uber
    scext
    ascext
    tbl0ext
    tlbext
    latexext
    slatexext
    texext

    Beispiel
    ========
      scext "sc"
      ascext "txt"
      tbl0ext "csv"
      tblext "tbl"
      latexext "latex"
      slatexext "slatex"
      texext "tex"
      set color
      #---------------------------------------------------------------------------
      # Nach Return zu Zelle darunter
      #  craction=1 nach unten
      #  craction=2 nach rechts
      #  ^tr <Pfeiltaste in gewuenschte Richtung>  => Toggle des Return-Verhaltens
      #---------------------------------------------------------------------------
      set craction=0
      format 5 = "0,.&"
      format 6 = "0,.& Eur"
      format 7 = "0,.& L"
      #---------------------------------------------------------------------------
      # Function Keys
      #   $$ ist die aktuelle Zelle => fuer Range-Angabe verdoppelt
      #---------------------------------------------------------------------------
      fkey 2 = "color $$:$$ 1"  # Zellfaerbung zuruecksetzen
      fkey 3 = "rightstring $$ = @ext(\"dateutils.ddiff \"#A1#\" \"#A2#\" #\",0)"
      #---------------------------------------------------------------------------
      # Alternative, wenn neg. Zahlen in Klammern dargestellt werden sollen
      #---------------------------------------------------------------------------
      # format 5 = "0,.& Eur;(0,.& Eur)"
      # format 6 = "0,.&;(0,.&)"
      #---------------------------------------------------------------------------
      # Farben
      #   Cave: color 2 ist Farbe fuer negative Zahlen, wenn deren Kennzeichnung mit
      #     ^TN
      #     S colorneg
      #   gesetzt ist
      #---------------------------------------------------------------------------
      color 1 = @black;@white
      color 2 = @yellow;@white
      color 3 = @blue;@white
      color 4 = @green;@white
      color 5 = @red;@white
      color 6 = @magenta;@white
      color 7 = @cyan;@white

Navigation
==========
  ^E(jklm) => zur naechsten (nicht-)leeren Zelle oben,unten,links,rechts
    je nachdem, ob die aktuelle Zelle leer oder nicht-leer ist
  0  erste Zelle der Reihe
  $  letzt Zelle der Reihe
  ^  Oberste Zeile
  #  Unterste Zeile
  j,k,l,m  == Pfeiltasten
  ^Y und ^E Bildschirm 1 Zeile nach unten, oben
  g B100 Gehe zu Zelle B100

^t Toggle Options
   ^ta automatische Neuberechnung
     => explizite Neuberechnung mit '@'
   ^tC (toggle Color)
   ^tN (toggle Color fuer negative Zahlen => Farbpaar 2)
   ^tE (toggle Color fuer fehlerhafte Zellen)
   ^tr <Pfeiltaste> (toggle Bewegung nach Return)
   ^c  Cell-Highlighting (Highlighting vs. <=) 
S Set Options => Menue oben; jedoch nur Teilauswahl der Optionen der Manpage, besser als Auswahl ist Direkteingabe
    locale # Tausendertrennzeichen und Dezimalpunkt (nicht ueber ~/.scrc zu erreichen :-/)
    color
    craction=0,1,2
    tblstyle=
      0                   <= entspricht CSV-Ausgabe mit ':'
        delimiter ':'   
      tbl
        delimiter ':'
      latex
        delimiter '&'
      slatex
        Scandinavian Latex
      tex
        delimiter '&'
      frame
        Framemaker
      
@  Neuberechnung (z.B. falls automatische Neuberechnung mit ^ta deaktiviert wurde)
mx Markiere Zelle durch Puffer x 
'x springt wieder zu Zelle (analog vim)
cx Kopiert zuvor mit mx markierte Zelle
   'c.' ist Sonderfall von 'rc'
     aktuelle Zelle wird als source range vorbelegt, destination range kann wie gewohnt mit
       - Cursorbewegung <RETURN>
         - aktuelle Zelle wird hier auch Teil des destination range
       - <TAB> <BACKSPACE> [ueberschreiben], z.B. <TAB><BACK> C4:H4 <RETURN>
     angegeben werden

"x Naechstes yank/delete/pull-Command in Buffer x
z<Ret> Zeile wird erste Zeile des Bildschirmes
z. Zeile wird mittlere Zeile des Bildschirmes
z| Spalte wird mittlere ...
zc Zelle wird Bildschirmzentrum
= Zahleneingabe
><\ Stringeingabe rechts, links, zentriert 
  mit '"' beginnen, Abschluss-'"' wird automatisch gesetzt
  Beginnt der String selbst mit '\' wird das folgende Zeichen als Fueller der Spalte verwendet
    >\-   => "------"
    <\-   => "------"
    \\-   => "------"
    
    Cave: Hier muss das schliessende Hochkomma wegen des Whitespace manuell gesetzt werden
      >\+ " => "+ + + + "
{|} String ausrichten links, rechts, zentriert
F Zelle formatieren (cf. auch rF unten)
  Es kann hier auch ein Range eingegeben werden
    F B4:B8 "#,0.& \Liter"
  # Zahl
  0 Zahl mit 0-Padding
  . Dezimalpunkt
  % Prozentzahl durch Multiplikation mit 100
  , Tausendtrenner
  & Nachkommastellen werden mit 0 aufgefuellt, bis Zellvorgabe fuer Dezimalstellen erreicht
  \ Quotierung des naechsten Zeichens
  ; Eingabe getrennter Formate fuer positive und negative Zahlen

  Datumsformatierungen mit den Symbolen aus 'man strftime' und vorangestelltem Ctrl-D, also etwa
    Ctrl-D%T => angezeigt als "^D%T" (z.B. fuer Inhalt =@dts(2021,12,31) => Ausgabe als (wenig sinnvoll) 00:00:00)
    
# konkateniert Strings
    A1#A2
    "Hugo "#B17
  
>\- Fuegt durchgehende Linie in Zelle ein

Zr zap row
 6Zr  6 Zeilen ausblenden
Zc zap column
sr show row <Auswahl>
sc show column <Auswahl>

<Zahl>f Spalten formatieren (Breite, Dezimalstellen, Formatierungsnummer)
                      Pfeil links/rechts => Spaltenbreite  (alternativ: h,l)
                      Pfeil auf/ab       => Dezimalstellen (alternativ: j,k)
                      <Zahl>             => Formatnummer (cf. unten)
                      (h,j,k,l oder Pfeiltasten, numerische Tasten fuer Formatierungsnummer)
                                                 0 Fixed
                                                 1 scientific
                                                 2 engineering
                                                 3 dates (Jahr 2-stellig)
                                                 4 dates (Jahr 4-stellig)
                                                 5-9 eigene vordefinierte Formate (cf. f=<Zahl>)
      Beispiel: F "#,0.& \Eur" <RETURN>
      Tipp: Format kann nach Ctrl-C mit Shift-Ins eingefuegt werden 

<Zahl>f<Blank> wie oben, jedoch mit Editierung der Formatangaben in der obersten Zeile
f=<Zahl> Definition des Spaltenformates <Zahl>
         Formatierungsangaben wie unter F
         Beispiel: format = (Auswahlmenue 0-9 erscheint) 5 "#,0.& ;(#,0.&)"


g H3  => "go" H3
e Zahl editieren
E String editieren
Zeilen- und Spaltenkommandes (optional: Zahlangabe vorher)
ir,ic (insert row, column)  
  4ic (4 Spalten einfuegen)
ar,ac (Aktuelle Zeile, Spakte kopieren "append") 
  5ar 5 mal die aktuelle Zeile kopieren
dr,dc Beispiel: 5dr
or,oc
dd Aktuelle Zelle loeschen
x  Aktuelle Zelle loeschen
yr,yc,yy (Abfolge: yr => pr; yy => pp oder pf; yc => pc)
  2yr 2 Zeilen kopieren
   pr (vorige) 2 Zeilen einfuegen
  3yc 3 Spalten kopieren
   pc (vorige) 3 Spalten einfuegen
pr,pc,pp pull
      pC (wie pp, aber Aenderung der Zell-Referenzen)
      p. (wie pC, aber mit Abfrage des Ziel-Ranges)
         Ziel-Range-Eingabe wie immer mit <TAB> <BACK> und Ueberschreiben
         erspart quasi, zunaechst zu Zielzelle zu wechseln und pC einzugeben
      pm (mergen statt einfuegen)
         ueberschreibt in Zielzelle bei zuvor kopiertem String nur deren String-Wert,
         waehrend ein numerischer Wert in der Zielzelle beibehalten wird
      pf (genau und nur Formatierung mergen nach z.B. vorherigem yy)
         Cave: Farben gehoeren NICHT zur Formatierung
         Formatierung ist ein zuvor mit F oder rF gesetztes Format der Quellzelle/des Quell-Range
         die mit f festgelegte Formatierung der Quell-Spalte wird NICHT in die Ziel-Spalte uebertragen
      px (exchange Quelle (Delete-Buffer) und aktuelle Zelle)
      pp (paste)
         Cave: Zell-Referenzen werden NICHT updated => bei Zellbezuegen pC verwenden
vr,vc,vv Formeln in (je nach Ausgabeformat der Zelle(n)) Strings oder Zahlen wandeln
Zr,Zc,ZZ Ausblenden
sr,sc Einblenden

Range-Commands: links oben (in Zielrange) positioneren, Kommando eingeben, Range mit Pfeiltasten auswaehlen und <TAB>
Tipp: Anstelle Cursorbewegung oder expliziter Eingabe 'A10:A40' koennen auch Wiederholung und Richtung angegeben werden (10j, 5l, 3h, ...)
      Beispiel: rf 10l <TAB> 10 1 <RETURN>

rx Range loeschen => p-Kommandos
ry Range yank (Referenzen fix) => p-Kommandos
rc Kopiere Destination-Range <= Source-Range
           Quelle kann einzelne Zelle sein => Range A2:A2

   Besonderheit: Zell-Bezuege werden aktualisiert (cf. pp vs. pC oben)

   Vorgehen
     Links oben in Zielrange positionieren
     (ggf. Zielrange mit Maustasten vergroessern)
     rc <Tab>
     Quellrange eintippen (C17:C26) 
     <RETURN>
rm fast wie rc, aber 'move'
   Vorgehen
     Links oben in Zielrange positionieren
     rm <Tab> <Tab>
     Ergaenzung des zweiten <TAB> mit Quellrange ueberschreiben (C17:C26) 
     <RETURN>
rr range-range (outrange und innerrange) => "freeze"
     outrange beinhaltet innerrange
     die "Differenz" wird nicht scrolled
     Auswahl der Range-Art mit Anfangsbuchstaben der Auswahlliste nach rr <TAB>
       hier: a(ll) auswaehlen
     rr a(all) <TAB> A0:Z100 A1:Z100
       friert die oberste Zeile ein und erzeugt den Dateieintrag
         frame A0:Z100 A1:Z100
rv Formeln in Zahlen wandeln
rs Sortieren mit Angabe von 3 Parametern 
   Vorgehen
     Links oben im Range positionieren
     rs (ggf. mit Pfeiltasten markieren und) <Tab> 
     Rangeangabe vervollstaendigen (eintippen oder mit Pfeiltasten bewegen)
     optional: Sortieranweisungen in "..." eingeschlossen (auch mehrere Spalten nacheinander)
       + oder -
       # oder $ (# fuer numerisch, $ fuer String)
       <Spalte innerhalb Range, nach welcher sortiert wird>
       Default ist "+$", also alphabetisch aufsteigend

       Beispiel: 
         rs <Pfeiltasten Range markieren> <Tab> "-$A" <RETURN>
         rs <Tab><BACK> A1:D10 "+#B" <RETURN>
         rs <TAB><BACK> A1:A10 <RETURN>
         rs <TAB><BACK> A1:D10 "-$A+#B" 
           zuerst alphabetisch absteigend nach A
           danach numerisch aufsteigend nach B
         rs <TAB><BACK> A1:D10 "+$A+#A" 
           entweder alphabetisch oder numerisch aufsteigend in A

rf Range fuellen
   Vorgehen
   rf
   Range mit Navigationstasten markieren
   <TAB>
   Startwert
   Inkrement
   <RETURN>
   Beispiel: 
     rf <Pfeiltasten> <Tab> 10 5 <Return>
     rf 10j <Tab> 10 5 <RETURN>
r{ Range ausrichten
r}
r|
rS Rangedefinitionen anzeigen (z.B. auch Farbwerte)
rF Range formatieren
   Rangeauswahl mit Pfeiltasten
   <Tab>
   Formatangaben wie unter F

   Beispiel: rF <Pfeiltasten> <Tab> "#,0.& \Eur" <RETURN>
   Tipp: Format kann nach Ctrl-C mit Shift-Ins eingefuegt werden 

rC Farbrange anlegen
   Rangeauwahl wie immer (Links oben positionieren, Pfeiltasten, <TAB>)
   gefolgt von Farbnummer (1-8) und
   <RETURN>

Farben
  rS u.a. alle Farbdefinitionen anzeigen
  1 ist immer Defaultfarbpaar
  2 Farbe fuer negative Zahlen, wenn colorneg gesetzt
    S colorneg oder
    ^TN
  3 Farbe fuer fehlerhafte Zellen
    S colorerr
    ^TE
  4 Farbe fuer Felder mit Notizverweisen
  C Farbdefinition fuer Auswahl aus 1-8 setzen
    ohne Formatangabe => loeschen der Farbdefinition
    Formatangabe: @white;@green (Vordergrund und Hintergrund)
    falls bereits Format definiert war, wird dieses zur Editierung angezeigt
    Defaultfarben
      color 1 = @white;@blue
      color 2 = @red;@blue
      color 3 = @white;@red
      color 4 = @black;@yellow
      color 5 = @black;@cyan
      color 6 = @red;@cyan
      color 7 = @white;@black
      color 8 = @red;@black
Notizen
*a legt Link zu Zielzelle (mit Kommentar an)
   Angabe der Zielzelle wie immer mit <TAB> <TAB> <BACK> Ueberschreiben
** springt zu Zelle mit Kommentartext
*d Kommentarverweis loeschen
*s zeigt Zellen mit Kommentarverweis durch Kontrastfarbe

Funktionen/Formeln
==================
  Fuer alle elementar und wichtig:
    Elemente einer Formel koennen entweder Strings oder numerische Werte sein
      demgemaess muessen Werte und Zellbezuege innerhalb von Formeln ggf. zu Strings oder numerischen Werte gewandelt werden
        @ston(A17)
        @fmt("%.sf",B101)
    Das Ergebnis einer Formel kann entweder ein String oder numerischer Wert sein
      demgemaess muss bereits die Formel selbst entweder als numerischer Wert oder String eingegeben werden
        =@if(....)  => Ausgabe in numerisches Feld der Zelle
        @if(...)    => Ausgabe in String-Feld der Zelle
          Damit die Formel selbst als solche und nicht Text interpretiert wird, muss das von sc automatisch zu Beginn
          der String-Eingabe eingefuegte Hochkomma zunaechst geloescht werden, also
            @if(...) 
          und nicht
            "@if(...)

  @sum
  ====
    Bedingte Summierung (wie auch andere bedingte Funkionen)
      Falls der Bedingungsausdruck sich auf eine andere Spalte bezieht, wird genau und nur deren oberste Vergleichszelle angegeben.
      Die untere Vergleichszelle ergibt sich aus der Summationsspalte
    @sum(A0:A3)                  <= unbedingte Summation von A0 bis A3
    @sum(A0:A3,@eqs(B0,"ja"))    <= bedingte Summation   von A0 bis A3, sofern Bedingung jeweils in B0 bis B3 erfuellt ist

       A             B
    0  1.0                        <- Beginn der bedingten und unbedingten Summation
    1  2.0           "ja"
    2  3.0           "ja"
    3  4.0                        <- Ende der bedingten und unbedingten Summation
    4  5.0           "ja"         <- wird nicht mehr bedingt summiert
    5
    6  =@sum(A0:A3)  =@sum(A0:A3,@eqs(B0,"ja"))

  =>   9             5 


  Externe Funktionen
  ==================
    @ext(se,e) 
      se: Erster Teil der Kommandozeile: muss String oder Verkettung von Strings sein (oder Bezug auf String-Wert einer Zelle)
            
       e: Zweiter Teil der Kommandozeile: muss numerischer Wert sein (oder Bezug auf numerischen Wert einer Zelle) und wird implizit zu String gewandelt
          Cave: Dennoch ist NICHT moeglich, gleich einen String anzugeben oder auf den String-Wert einer Zelle zu verweisen

      Der Trick ist daher, den gesamten Aufruf in Teil 1 als Verkettung von Strings zu verpacken und diese Kommandozeile mit
      dem Bash-Kommentarzeichen '#' so abzuschliessen, dass Teil 2 nur als Kommentar in den Gesamtaufruf kommt
      (cf. hierzu auch 'man sc')

      Cave: Das Konkatenierungszeichen fuer sc ist ebenfalls ein '#' ;-)

      Beispiele
      =========

        Beispiel 1
        ==========
        Konkatenierung von Strings

        #######################Externe Funktion ist ein Bash-Script###############################
        #!/bin/bash
        #-------------------------------------------------------------
        # Test-Script mytest
        #-------------------------------------------------------------
        printf "Arg1: (%s) Arg2: (%s)\n" "$@"
        #######################Externe Funktion Ende##############################################

        Cave: Im folgenden ist '#' das sc-Konkatenierungszeichen UND das Bash-Kommentarzeichen vor dem damit auskommentierten zweiten Teil der Kommandozeile '0'
        Cave: Das Ergebnis von @ext ist wiederum ein String, KEINE Zahl !
              Anschliessend daher mit @ston in Zahl wandeln (wenn mit dem Ergebnis weitergerechnet werden soll)
              Cave: Wandlung in EINEM Schritt, d.h. Zahlausgabe in die Zelle mit der @ext-Formel, scheint nicht moeglich

             A            B              C                                                   D
        1    2021-01-01   2021-01-31     @ext("mytest "#A1#" "#B1#" #",0)                                            => Arg1: (2021-01-01) Arg2: (2021-01-31)
        2    2021-01-01   2021-06-31     @ext("dateutils.ddiff "#A2#" "#B2#" #",0)                                   => 180 (String)
        3    2021-01-01   2021-06-31     @ston(@ext("dateutils.ddiff "#A3#" "#B3#" #",0))    =@ston(C3)/2            => 180 (String) => 90 (Zahl)


        Beispiel 2
        ==========
        Konkatenierung von Strings und numerischen Werten

        #######################Externe Funktion ist ein Bash-Script###############################
        #!/bin/bash
        #-----------------------------------------------------------------------------------------
        # Externe Funktion fuer sc-Tabellenkalkulation: myscsollcell
        #-----------------------------------------------------------------------------------------

        . /usr/bin/common   # fuer Funktion 'calc'

        steuerKonto=$1
        buchung=$2

        if [[ "$steuerKonto" =~ ^[0-9]+$ ]]; then
          case "$steuerKonto" in
            1568) printf "%s\n" $(calc "$buchung / 1.05" 2 2) ;;
            1571) printf "%s\n" $(calc "$buchung / 1.07" 2 2) ;;
            1575) printf "%s\n" $(calc "$buchung / 1.16" 2 2) ;;
            1576) printf "%s\n" $(calc "$buchung / 1.19" 2 2) ;;
            1771|1773|1775|1776) printf "%s\n" $buchung ;;
            *) printf "%s\n" 0 ;;
          esac
        else
          printf "%s\n" 0
        fi
        #######################Externe Funktion Ende##############################################


           A         B            C
        0  Konto     Buchung     
        1  1568      100.0        @ext("myscsollcell "#A1#" "#@fmt("%.2f",B1)#" #",0)}           <= Verkettung wie in Beispiel 1, jedoch Wandlung von B1 in String => ergibt 95.23 (= 100.0/1.05)

                                                   
     Cave: Vor Duplizierung von @ext-Formeln
             mit (Toggle-Befehl)
               ^ta
             Auto-Aktualisierung ausschalten (sonst Core-Dump)
             rc-Befehl ausfuehren
             mit
               @
             alle Berechnungen aktualisieren
             und Auto-Aktualsierung wieder einschalten

           Alternativen: Formel als Text kopieren mit STRG+SHIFT+C und wiederholt einfuegen mit SHIFT+EINF (und editieren)
             Tipp: Text als Hotkey belegen (cf. unten)
               fkey 5 = "rightstring $$ = @ext(\"dateutils.ddiff \"#A1#\" \"#A2#\" #\",0)"

  @if-Anweisungen
  ===============

      Falls Stringausgabe:                                  
        Numerischer Vergleich
          @if(C126=100,"Dr. Breinlinger","Sonst jemand")   
        String-Vergleich
          @if(@eqs(C126,"Heinz")?"Dr. Breinlinger,"Sonst jemand")
      Falls numerische Ausgabe:  
        Numerischer Vergleich
          =@if(C126=100|C126=50,1,2)
        String-Vergleich
          =@if(@eqs(C17,"Passt"),1,2)

      Alternative via Operator e?e:e        @eqs(C126,"Heinz")|@eqs(C126,"Willi")?1:2

      Cave: Rekursionen sind nur durch Klammern des jeweils gesamten Else-Zweiges einer jeden Rekursion moeglich:

        Beispiel
        ========

        Falls Feld G304 die String-Werte "1568","1571","1575","1576" annimmt: Jeweils verschiedenen Berechnungen

                                       ( Else-Zweig 1                  ( Else-Zweig 2                  ( Else-Zweig 3                   )))
        @eqs(G303,"1568")?D4/1.05*0.05:(@eqs(G303,"1571")?D4/1.07*0.07:(@eqs(G303,"1575")?D4/1.16*0.16:(@eqs(G303,"1576")?D4/1.19*0.19:0)))


Programmierbare Funktionskeys
=============================

  fkey <nummer> = "command"
    in ~/.scrc oder *.sc oder auf command-line
      command ist JEDE (!) Anweisung, wie sie auch in einer *.sc-Datei vorkommt
      $$ bezeichnet die aktuelle Zelle => fuer Range-Angabe also verdoppeln (A2 => A2:A2)

      Beispiele

        fkey 2 = "color $$:$$ 1"  <= "entfaerbt Zelle", sofern Farbe 1 schwarz/weiss darstellt
        fkey 9 = "fmt $$ \""0,.& Eur\""
        fkey 4 = "let $$ = @myrow"
        fkey 5 = "rightstring $$ = @ext(\"dateutils.ddiff \"#A1#\" \"#A2#\" #\",0)"
          => erzeugt natuerlich, so die Dummy-Zellwerte A1,A2 keinen Datums-String beinhalten, eine Fehlermeldung
             und ist nach Einfabe ueber <F5> schlicht mit E zu editieren :-)

Macros
======

cf. Anmerkungen zu Beginn

R *.sc-Datei
  fuehrt Befehle der eingelesenen *.sc-Datei aus

  R Macro.sc

A *.sc-Datei
  laedt *.sc-Datei bei naechstem Start der aktuellen Datei automatisch

  A Macro.sc

D <Macro-Verzeichnis>

  Definiere Verzeichnis fuer mit R oder A angegebene Macro-Dateien

Vermischtes
===========

CTRL-X zeigt alle Zellen mit numerischen Werten, welche aus Formlen resultieren
CTRL-R ist das genaue Gegenteil => Anzeige aller Zellen mit numerischen Werten OHNE Formeln

Top

screen

Command-Line-Mode (analog ex)

C-a :
  resize -v + 20
    Vertikal plus 20 Zeilen
  resize =
    Gleiche Groesse aller Teilfenster


Detach/Reattach
===============
ssh heinz@nas
screen
Ctrl-A Ctrl-d (oder einfach nur 'd')

screen -r(esume)

Wurden mehrere Sitzungen detached praesentiert
  screen -r
eine Auswahl

screen -R -D (screen -RD)
  Reattach or create session


screen 
screen -r (reattach)

Wichtig: Nach Split in neue Region wechseln (C-a <TAB>) und dort neue Shell kreieren (C-a c) oder zuweisen (C-a 1)

Wichtigste Befehle
C-a gefolgt von
  : => Command-Line-Mode
    title Fenstertitel vergeben
  A Fenstertitel vergeben
  c (create new window and shell)
  Q (Nur aktuelles Fenster (jedoch alle Shells) behalten) z.B. um Split-Windows zu schliessen
  S (horizontaler Split)
  | (vertikaler Split)
  " Fensterliste
  <blank> naechste Sitzung/Shell
  n naechste Sitzung/Shell
  N zeige Nummer der Sitzung/Shell
  d detach
  0-9 Sitzung mit Nummer
  C-\ Alle Sitzungen und screen beenden
  ? Hilfebildschirm
  <TAB> naechste Region (bei Split)

Top

tmux

Unterscheidung
  Windows
  Panes (Unterteilungen ein und desselben Fensters)

Sessions
  tmux ls (list sessions)
  tmux kill-session -t myname
  Ctrl-B d detach
  tmux a(t(ach)) attach
  tmux new -s myname Neue Session "myname"
  tmux a -t myname (re)attach session "myname"

Panes
  Ctrl-B "                     Split horizontal
  Ctrl-B %                     Split vertikal
  Ctrl-B x                     Kill pane
  Ctrl-B <Pfeil>               Pane wechseln
                               auch schnelle Kombination von Pfeilen nach Ctrl-B moeglich
  Ctrl-B q                     Anzeige der Pane-Nummern
  Ctrl-B o                     Pane-Wechsel
  Ctrl-B Ctrl-o                Pane-Rotation
  Ctrl-B z                     Toggle Pane-Fullscreen
  Ctrl-B Alt 1-5               Pane-Anordnung nach Voreinstellung 1-5
                               Cave: 5 == tiled
  Ctrl-B Ctrl <Pfeil>          Pane-Größe in 1er-Schritten ändern
  Ctrl-B Alt  <Pfeil>          Pane-Größe in 5er-Schritten ändern
  Ctrl-B {}                    Pane-Swap (previous|next)

Windows
  Ctrl-B c Neues Fenster
  Ctrl-B n Wechsel zu naechstem Fenster
  Ctrl-B p Wechsel zu vorherigem Fenster
  Ctrl-B 0-9 Wechsel zu Fenster 0-9
  Ctrl-B w Anzeige aller Fenster (analog Ctrl-A " bei screen)
  Ctrl-B & kill windows
  Ctrl-B , name window

In .tmux.conf anlegen, um letzten Pfadbestandteil in Statusleiste anzuzeigen 
  set-option -g status-interval 15
    (Cave: status-interval ist das Update-Intervall in Sekunden)
  set-option -g automatic-rename on
  set-option -g automatic-rename-format '#{pane_current_path}'
    cf. man tmux
      b: => basename 
        set-option -g automatic-rename-format '#{b:pane_current_path}'
      d: => dirname 
        set-option -g automatic-rename-format '#{d:pane_current_path}'

Top

sed

sed -n /anfang/,+3{   # Cave: +3 und ~3 (naechstes Vielfaches von 3) erlaubt, -3 nicht
  p
}

sed '{
  /sed /{
          i\
  }
}' Howto.txt > out

--------------------------------------------------------------------------------------------------------------------

      sed -i -e '/verrechnet/!{                              # Nur Zeilen ohne "verrechnet"-Vermerk
                   /^'${dateOfBooking}';'${value}'/{         # Potentieller Match
                      x                                      # Tausch: Pattern-Space <-> Hold-Space
                      /verrechnet/{                          # War "verrechnet" in Hold-Space ?
                        x                                    # Pattern-Space wiederherstellen
                        b                                    # Keine weiteren Kommandos anwenden und Zeile ausgeben
                      }
                      /verrechnet/!{                         # Kein "verrechnet" in Hold-Space gewesen ?
                        x                                    # Pattern-Sapce wiederherstellen
                        s/^\('${reverseDateOfBooking}';'${value}'.*\)/\1 verrechnet/    # "verrechnet anhaengen"
                        h                                                               # Zeile mit Verrechnungsvermerk in Hold-Space kopieren
                      }
                   }
                 }' $commentFile

--------------------------------------------------------------------------------------------------------------------

    sed -i -n -e '1,/;"*'$paenultSaldo'"*$/ {   # Von erster Zeile bis Zeile mit Eintrag $paenultSaldo
                    /;"*'$paenultSaldo'"*$/d    # letzte Zeile loeschen
                    p                     # andere Zeilen ausgeben
                  }' $ultima

--------------------------------------------------------------------------------------------------------------------

sed -i -n -e '/^'${yearOfInterest}'/p' -e '/^Datum/p' "${resultFile}"

--------------------------------------------------------------------------------------------------------------------

    sed -i ${lineNum}'s/!'${table}'!/!'${table}${count}'!/' "${file}"

--------------------------------------------------------------------------------------------------------------------

  sed -n '
    /BEGIN:VEVENT/,/END:VEVENT/{
      /DTSTART/{
        s/DTSTART;VALUE=DATE://
        s/DTSTART://
        s/DTSTART;TZID=Europe\/Berlin://
        s/"//g
        s/\\//g
        h                     # Hold-Space
      }
      /DESCRIPTION/{
        s/DESCRIPTION:\(.*\)/(\1)/
        H                     # Netto-Beschreibung geklammert an Hold-Space anhaengen
      }
      /SUMMARY/{
        s/SUMMARY://
        s/"//g
        s/\\//g
        H                     # an Hold-Space anhaengen
        g                     # Hold-Space => Pattern-Space
        s/\(.*\)\n\((.*)\)\n\(.*\)/\1: \3 \2/ # Reihenfolge der durch Newline getrennten 3 Teile andern: Datum/Zeit\n(Kommentar)\nTitel => Datum/Zeit: Titel (Kommentar)
        s/()//                # Leere Kommentare loeschen
        p
      }
    }
  ' "$icsFile" > "$patternFile"

--------------------------------------------------------------------------------------------------------------------

      sed -i -e '/<d19/{ 
                   /<\/d19/!{ 
                     N 
                     s/\n/ /g 
                   } 
                 }' $rawXml
      checkReturn sed

--------------------------------------------------------------------------------------------------------------------

sed -i \
  's///g # alle von Griechisch-Lexer stets belassenen  entfernen
   s/ä/\ä/g 
   s/ö/\ö/g
   s/ü/\ü/g 
   s/Ä/\Ä/g 
   s/Ö/\Ö/g 
   s/Ü/\Ü/g 
   s/ß/\ß/g 
   s/(em\([[:alpha:]]\+\)[[:space:]]\+\([^)]\+\))/<em class="\1">\2<\/em>/g 
   s/(li[[:space:]]\+\([^)]\+\))/<li>\1<\/li>/g 
   s/(img[[:space:]]\+\([^)]\+\))/<img src="\1" width="10%" height="10%" alt=""\/>/g 
   s/(imgb[[:space:]]\+\([^)]\+\))/<img src="\1" width="10%" height="10%" alt="" border="1"\/>/g 
   s/

/<br\/><br\/>/g s/
/<br\/>/g' "$file" -------------------------------------------------------------------------------------------------------------------- sed -n '/Filter.*stream/,/^endstream/ { /Filter.*stream/d /^endstream/d p }' "$qualInFile" > "$qualOutFile" -------------------------------------------------------------------------------------------------------------------- sed -n -e '/<Placemark>/,/<\/Placemark>/{ # Innerhalb eines Placemark-Tags #------------------------------------------------ # Bei gefundenem Pfad Pfad-Marker setzen und # Anfang eines Placemark-Tags ausgeben #------------------------------------------------ /Path/{ # "Path" vorhanden ? s/.*/Pfad_gefunden/ # Pfad-Marker erzeugen h # Pfad-Marker => hold space #------------------------------------------------ # Anfang eines Placemark-Tags ausgeben #------------------------------------------------ i\ <Placemark>\ <name>$name</name>\ <styleUrl>#lineStyle</styleUrl>\ <Style>\ <LineStyle>\ <color>ff0000ff</color>\ <width>5</width>\ <scale>5</scale>\ </LineStyle>\ </Style>\ <LineString>\ <tessellate>1</tessellate>\ <coordinates> } #--------------------------------------------------- # Bei Ende eines Placemarks mit Pfad Pfad-Marker in hold space loeschen # und Placemark-Tag in der Ausgabe abschliessen #--------------------------------------------------- /<\/Placemark>/{ # Placemark-Ende g /Pfad_gefunden/{ # Pfad-Marker vorhanden ? s/.*// # Leerstring erzeugen h # => Pfad-Marker in hold space loeschen #------------------------------------------------ # Ende eines Placemark-Tags ausgeben #------------------------------------------------ i\ </coordinates>\ </LineString>\ </Placemark> } } #--------------------------------------------------- # Zahlentupel # 6.451126,51.664082,22.18 #--------------------------------------------------- /^[[:digit:]\., ]*$/{ # Falls Zahlentupel G # hold space mit Newline anhaengen /Pfad_gefunden/{ # Pfad-Marker vorhanden ? P # Zahlen (bis Newline) ausgeben } } }' "$infile" >> $outfile -------------------------------------------------------------------------------------------------------------------- sed -n -e '/EXTINF/{ #---------------------------------------------- # Angaben vor Sendernamen loeschen, # Leerzeichen aus letzterem entfernen, # Umlaute ersetzen, # Sendername gross schreiben #---------------------------------------------- s/#EXTINF:[,0-9 ]\+// s/ /_/g s/Ä/Ae/g s/Ö/Oe/g s/Ü/Ue/g s/ä/ae/g s/ö/oe/g s/ü/ue/g s/.*/\U&/ #---------------------------------------------- # Streaming-URL in naechster Zeile lesen #---------------------------------------------- N #---------------------------------------------- # Zeilen Verketten #---------------------------------------------- s/\n/:/ #---------------------------------------------- # Verkettetung ausgeben #---------------------------------------------- p }' "$file" -------------------------------------------------------------------------------------------------------------------- sed -n \ -e '/^\(leftstring\|rightstring\|label\|let\)/ { #------------------------------------------------------------------------------ # Ersetzung aller Zellenbezeichner mit 1-stelliger Zeile: # rightstring AC1 = "Hugo ist lieb" # => # rightstring 001AC = "Hugo ist lieb" #------------------------------------------------------------------------------ s/^[[:alpha:]]\+ \+\([[:alpha:]]\+\)\([[:digit:]]\{1\}\) /00\2\1 / #------------------------------------------------------------------------------ # Ersetzung aller Zellenbezeichner mit 2-stelliger Zeile: # let Q23 = 0.544*$B$7 # => # let 023Q = 0.544*$B$7 #------------------------------------------------------------------------------ s/^[[:alpha:]]\+ \+\([[:alpha:]]\+\)\([[:digit:]]\{2\}\) /0\2\1 / #------------------------------------------------------------------------------ # sc-Funktionen => ODF-Funktionen, bitte ergaenzen #------------------------------------------------------------------------------ s/@sum/summe/g #------------------------------------------------------------------------------ # Dezimalpunkt => Dezimalkomma #------------------------------------------------------------------------------ s/\([[:digit:]]\)\.\([[:digit:]]\)/\1,\2/g #------------------------------------------------------------------------------ # Einfuegen des "Internal Field Separators": " = " => "|" #------------------------------------------------------------------------------ s/ \+= \+/|/ #------------------------------------------------------------------------------ # Vor Rechenausdruecken, also nicht nur einer einzigen (!) Zahl, fuehrendes "=" # fuer ODF-Formeln einfuegen #------------------------------------------------------------------------------ # Falls kein String, also kein Textfeld, damit also Zahl oder Rechenausdruck #------------------------------------------------------------------------------ /["]/! { #---------------------------------------------------------------------------- # Falls rechts von "|" bis Zeilenende nicht nur eine einzige Zahl mit optionalem Dezimaltrenner #---------------------------------------------------------------------------- /|[[:digit:]]\+,\{0,1\}[[:digit:]]\+$/! { #-------------------------------------------------------------------------- # fuehrendes '=' fuer Formelerkennung in ODF einfuegen #-------------------------------------------------------------------------- s/|/|=/ } } p }' $infile | sort > $tmpfile -------------------------------------------------------------------------------------------------------------------- sed -e '/^-/d' \ -e '/ *\(Summe\|Datum\|Soll\)/d' \ "$account" | sort -b -t '|' -k 3 > "$out" -------------------------------------------------------------------------------------------------------------------- sed -i -n '/^\('${chapters//,/\\|}'\);/p' "$randomFile" -------------------------------------------------------------------------------------------------------------------- done < <(sed -n "$startLine,${endLine}p" "$infile") -------------------------------------------------------------------------------------------------------------------- sed '/^<synonym>/{ s/ᾰ́\|ā\|ά\|ᾱ\|ἄ\|ά\|ὰ\|α\|ἀ\|ἁ\|ἂ\|ἃ\|ἅ\|ἆ\|ἇ\|Α\|Ἀ\|Ἁ\|Ἂ\|Ἃ\|Ἄ\|Ἅ\|Ἆ\|Ἇ\|ᾲ\|ᾳ\|ᾴ\|ᾶ\|ᾷ\|Ὰ\|Ά\|ᾼ/a/g s/β\|Β/b/g s/γ\|Γ/g/g s/δ\|Δ/d/g s/έ\|ἔ\|έ\|ὲ\|ε\|ἐ\|ἑ\|ἒ\|ἓ\|ἕ\|Ε\|Ἐ\|Ἑ\|Ἒ\|Ἓ\|Ἔ\|Ἕ\|Ὲ\|Έ/e/g s/ζ\|Ζ/z/g s/h̃\|ή\|ἤ\|ἥ\|ή\|ὴ\|η\|ἠ\|ἡ\|ἢ\|ἣ\|ἥ\|ἦ\|ἧ\|Η\|Ἠ\|Ἡ\|Ἢ\|Ἣ\|Ἤ\|Ἥ\|Ἦ\|Ἧ\|ῂ\|ῃ\|ῄ\|ῆ\|ῇ\|Ὴ\|Ή\|ῌ/h/g s/θ\|Θ/q/g s/ΐ\|ῑ\|ĩ\|ί\|ί\|ὶ\|ι\|ἰ\|ἱ\|ἲ\|ἳ\|ἵ\|ἶ\|ἷ\|ἴ\|Ι\|Ἰ\|Ἱ\|Ἲ\|Ἳ\|Ἴ\|Ἵ\|Ἶ\|Ἷ\|ῖ\|Ὶ\|Ί/i/g s/κ\|Κ/k/g s/λ\|Λ/l/g s/μ\|Μ/m/g s/ν\|Ν/n/g s/ξ\|Ξ/c/g s/ό\|ὄ\|ό\|ὸ\|ο\|ὀ\|ὁ\|ὂ\|ὃ\|ὅ\|Ο\|Ὀ\|Ὁ\|Ὂ\|Ὃ\|Ὄ\|Ὅ\|Ὸ\|Ό/o/g s/π\|Π/p/g s/r\|ρ\|ῥ\|Ρ\|Ῥ/r/g s/σ\|ς\|Σ/s/g s/τ\|Τ/t/g s/ύ\|υ\|ὔ\|ύ\|ὺ\|ὐ\|ὑ\|ὒ\|ὓ\|ὕ\|ὖ\|ὗ\|Y\|Ὑ\|Ὓ\|Ὕ\|Ὗ\|ῦ\|Ὺ\|Ύ/u/g s/φ\|Φ/f/g s/χ\|Χ/x/g s/ψ\|Ψ/y/g s/w̃\|ώ\|ὤ\|ᾠ\|ώ\|ὼ\|ω\|ὠ\|ὡ\|ὢ\|ὣ\|ὥ\|ὦ\|ὧ\|Ω\|Ὠ\|Ὡ\|Ὢ\|Ὣ\|Ὤ\|Ὥ\|Ὦ\|Ὧ\|ῲ\|ῳ\|ῴ\|ῶ\|ῷ\|Ὼ\|Ώ\|ῼ/w/g s/>[^a-z]/>/ }' "$tmpFile" > "$outFile" -------------------------------------------------------------------------------------------------------------------- sed ' s/<img[^>]*>//g # nervige Images entfernen s/nowrap=""//g # stoerende Attribute entfernen s:</tr>:</tr>\n:g # Zeilenumbrueche nach Tabellenzeilen ' "$container" > "$containerTmp" -------------------------------------------------------------------------------------------------------------------- sed ' /Genehmigung steht aus/{ N # Naechste Zeile einlesen und s/\n// # Zeilenumbruch dazwischen loeschen } ' "$file" > "$tmp" -------------------------------------------------------------------------------------------------------------------- sed ' /placeholder_0/{ s//'"$time"'/ } /placeholder_1/{ r '$report' d # darf erst NACH read stehen } ' "$websiteTemplate" > "$website" -------------------------------------------------------------------------------------------------------------------- sed -n ' /<Beschreibung>/,/<\/Beschreibung>/{ /<Beschreibung>/d /<\/Beschreibung>/d s/^[[:space:]]*#// p } ' "$file" >> "$outfile" -------------------------------------------------------------------------------------------------------------------- sed ' /placeholder_0/{ r '$citation' d # darf erst NACH read stehen } /placeholder_1/{ s//'"$time"'/ } /placeholder_2/{ r '$websiteConfig' d # darf erst NACH read stehen } ' "$websiteTemplate" > "$website" -------------------------------------------------------------------------------------------------------------------- sed '/^[[:space:];]*$/{ d # Quasi-Leerzeilen loeschen } /AZDEPA/d # Vertragszeile loeschen /^[[:space:]]*Date/{ s/^/#/ # Header-Zeile kommentieren } s/[^[:space:]]\+greifend/uebergreifend/g # verungluecktes erstes Zeichen bei ..bergreifend korrigieren #---------------------------------------------------------------------------------------------- # Namenskorrekturen #---------------------------------------------------------------------------------------------- s/D.niel/Daniel/g /Kuelheim/{ s/Ren./Rene/ } /Fink/{ s/Marko/Marco/ } #---------------------------------------------------------------------------------------------- s/[[:space:]]\+€[[:space:]]\+//g # Euro-Zeichen mit Leerzeichen loeschen s/[[:space:]]\+;/;/g # Leerzeichen loeschen s/;[[:space:]]\+/;/g # Leerzeichen loeschen s/ä/ae/g s/ü/ue/g s/ö/oe/g s/Ä/Ae/g s/Ü/Ue/g s/Ö/Oe/g s/ß/ss/g s/[[:space:]]*Dr\.[[:space:]]*// # Akad. Titel loeschen ' "$infile" > "$infileTmp"

Top

awk

awk [ -F separator -FS=regex ] [ -v var=value ... ] [ -f prog  ... ] 
awk  -F '\t' '{ ... }' files
awk -FS="[\t\n]" ...
awk '{ ... }' var=willi *.tex var=heinz *.tex                             # 2 Durchlaeufe mit verschiedenen Initialisierungen VOR Verarbeitung jeweiliger Eingabedatei, aber NACH BEGIN-Abschnitt 
awk '{ print $n }' n=4 Datei_1 n=2 Datei_2
...  -v var=heinz                                                         # Variable wird VOR BEGIN-Abschnitt initialisiert

Modell
======

pattern { action }
pattern                                                                   # Default-Aktion: print
{ action }                                                                # Aktion ohne Bedingung == fuer jede Zeile
BEGIN und END                                                             # Special patterns
str1="hugo";
str2="willi";
str=str1 str2                                                             # Es gibt keinen speziellen Konkatenierungsoperator
a=(var1>var2) ? x^3 : x^4
$0 ~ /\.[ch]$/
/\.[ch]$/                                                                 # synonym ($0 ist Default-String)
$4 !~ /\.+,\.+/
-------------------------------------------------------
BEGIN {IGNORECASE=1}                                                      # Cave: Gilt global, nicht nur fuer 1 Vergleich
string=ABC
($0 ~ /a/)                                                                # case-insensitive-match
-------------------------------------------------------
NF == 0                                                                   # Leerzeile
NF > 3                                                                    # Anzahl Felder
NR < 5                                                                    # Zeilennummer
(NR == 3) && (FILENAME ~ /[0-9][a-z]/)                                    
(NR == 2),(NR == 9)                                                       # Fuer Zeilen 2-9
$1 == "Hugo" { print $2; }
/Hugo/ || /Willi/ { ... }
! /Franz/ { ... }
/<hugo>/,/<\/hugo>/                                                       # Innerhalb Tag
$1 == "on",$1 == "off" { ... }
echo "Heinz Willi Franz" | awk '{ print $3 $2 $1}                         # Nicht-Komma-separierte Elemente werden in awk konkateniert => FranzWilliHeinz
echo "Heinz Willi Franz" | awk '{ print $3,$2,$1}                         # ',' bewirkt Einfuegen des Default OFS (' ') => Franz Willi Heinz
awk '{ OFS="..."; print $1, $2 }                                          # Output-Field-Separator
awk '{ sum += length($0) } END { print "Summe: " sum }'                   # Garantierte Default-Initialiserung jeder Variable macht sum=0 unnoetig
awk '{ print $1, log($1) }' 
awk -v column=5 '{ sum+=$column } END { print sum/NR }'
awk '{ sum+=$NF; print $NF, sum }                                         # laufende Summe der letzten Spalte
awk '/pattern|pattern/ { print FILENAME ": " NR " : " $0}' files          # egrep-Ersatz
awk 'BEGIN { FS=OFS="\t" } { print $3, $2 }' infile > outfile
awk 'BEGIN { ORS="\n\n" } { print }' files                                # Leerzeilen einfuegen
awk 'BEGIN { ORS =" "; RS="<[^<>]*>" } { print }' *.html                  # Fortgeschritten: HTML-Tags werden zu record-separators, in Ausgabe durch ' ' ersetzt und damit praktisch entfernt
for (key in assocArr){
  if(assocArr[name] == var){
    break
  }
}

#---------------------------------------------------
#!/usr/bin/awk -f                                                         # Shebang erfordert -f-Option

{
  print "Na also " $0; 
}
#---------------------------------------------------
PROCINFO["sorted_in"] = "@ind_str_asc";                                   # Sortierung
#---------------------------------------------------
delete array[key]
if !(key in assocArr) ...                                                 # richtig
if(assocArr[key] != "")                                                   # falsch, da hierbei assocArr[key] (leer) angelegt wird
if ((key1,key2,key3) in tripleAssocArr)                                   # Elementpruefung bei 3-dimensionalem Hash
#---------------------------------------------------
getline
=======
getline var < file
while((getline $words[nWords++] < file) > 0){
  ...
}
#---------------------------------------------------
# Zuweisung einer Feld-Variable (hier auf sich selbst)
# ersetzt FS durch OFS in aktuellem record
#---------------------------------------------------
awk 'BEGIN{OFS=":"} {$1=$1; print}' < file                                # a b c d => a:b:c:d  # print gibt record OFS-getrennt aus
#---------------------------------------------------
cmd | getline

  "date" | getline now                                                    # command wird in '"' eingeschlossen !
  close("date")

  command="head -n 15 /etc/hosts"
  while((command | getline line) > 0){
  }
  close(command)
#---------------------------------------------------
tmp=/tmpfile
command="sort -n > " tmp                                                  # Cave: Konkatenation 2er Strings
for (key in assocArr){
  print key ": " assocArr[key] | command
}
close(command)
#---------------------------------------------------
tmp=/tmpfile
for (key in assocArr){
  print "name: " assocArr[key] > tmp
}
close(tmp)
system("sort < " tmp)                                                     # Cave: String-Konkatenation, Cave: Jeder Aufruf von system(...) startet neue shell
#---------------------------------------------------
system("cat <<EOF\neins\nzwei\ndreiEOF")
#---------------------------------------------------
myfunc(arg1,arg2,   result){                                              # Lokale Variable result wird in Deklaration deklariert und (Konvention) durch Whitespace getrennt
  result =arg1 " " arg2
  return result
}
myfunc("Hugo","Willi")
#---------------------------------------------------
Funktionen
==========
  passing convention:
    values are passed by value
    arrays are passed by reference
  myfunc(i,   j)                                                          # Konvention: lokale Variablen nach Argumenten durch White-Space getrennt (j ist lokal, aber uebergeben werden darf nur i)
  substr(string,start,len)
  toupper(string)
  tolower(string)
  index(string,pattern)
  match(string,regex)
    alternativ: string ~ regex
  sub(regex,replacement,string)
  gsub(regex,replacement,string)                                          # Default-string ist $0
    Cave: '&' in replacement fuegt match ein
      gsub([aeiou],"&&")                                                  # verdoppelt gefundene Vokale der aktuellen Zeile

  result=gensub(regex,replacement,howto,string)                           # Cave: Rueckgabe des Ergebnisses UND Faehigkeit zu back-references
    resource=gensub(/([[:alpha:]]+)[[:space:]]*,[[:space:]]*([[:alpha:]]+)/, "\\2_\\1", "g", resource);

  split(string,array,regex)                                               # Default-regex ist Wert von FS (field-separator) => Rueckgabe der Array-Laenge
  split(string,array,"")                                                  # Split jedes Zeichens
  split("",array)                                                         # Effizientes Loeschen von array

Top

mc

.config/mc/mc.ext

(Shift) F5                       # Copy
(Shift) F6                       # Move
F7                               # Verzeichnis anlegen
F8                               # Delete
F10                              # Beenden
F4                               # vim
F3                               # Viewer

 

Alt-,                            # Toggle Left/Right - Top/Bottom-Ansicht
Alt-t                            # Cycle Listing-Modes
Ctrl-T                           # Objekte selektieren/deselektieren
Ctrl-u                           # Panels tauschen
Ctrl-PgUp                        # Vaterverzeichnis
Alt-.                            # Toggle hidden files
Alt-i                            # Verzeichnis in Nachbar-Panel laden
Alt-o                            # Inhalt des Verzeichnisses in anderem Panel laden
Alt-H                            # Chronik
Alt-y                            # vorheriges Verzeichnis in Historie
Alt-u                            # naechstes Verzeichnis in Historie
Alt-?                            # Datei suchen analog 'find'
Alt-s <Anfangsbuchstaben>        # Springe zu Datei nach Muster ... (Wildcards * ?)
  mehrfach => naechster Treffer
Ctrl-\                           # Directory Hotlist
Ctrl-o                           # Toggle shell
Ctrl-space                       # Verzeichnisgroesse ermitteln (Anzeige im Panel)
Ctrl-x (s|l)                     # Symbolischen oder harten Link im anderen Verzeichnis anlegen
Ctrl-x c                         # chmod-Dialog
Ctrl-x d                         # Verzeichnisse vergleichen
Ctrl-x o                         # chown-Dialog
Ctrl-x t                         # Markierte Datei => Kommandozeile
(Alt|Ctrl)-Enter                 # Selektierte Datei => Shell
Shift-(Alt|Ctrl)-Enter           # Selektierte voll qualifizierte Datei => Shell
+                                # Dateien selektieren nach Muster
\                                # Dateien nach Muster deselektieren
*                                # Auswahl umkehren (nur Dateien)
cd .tgz *.tar.gz
cd ftp://....
  Ruecksprung: cd

Command-Line
  z.B. cd ...
    ESC-Tab => autocompletion
      mehrfach => Auswahl

Top

Win32OLE mit Ruby

Ruby-Snippets zu Win32OLE (WSH, Outlook, Excel, Word)


Windows-Scripting-Host
======================

  wsh.AppActivate(pid)
  wsh.SendKeys(key)
  wsh=WIN32OLE.new('WScript.Shell'); checkValue(wsh)
  wsh.run("cmd.exe /C start microsoft-edge:http://www.google.de");
  #---------------------------------------------------------------
  processArray=Array.new
  taskList=%x(tasklist)
  puts("----------------------")
  taskList.split(/\n/).each { |task|
    # if(task.match(/^#{processName}\S+\s+(\d+)/i))
    if(task.match(/^#{processName}\s+(\d+)/i))
      puts("Job: #{$1}")
      processArray << $1
    end
  }

Win32OLE
========

  Outlook
  =======
    #---------------------------------------------------------------
    $outlook=WIN32OLE.new('Outlook.Application'); checkValue($outlook)
    $outlook=WIN32OLE.connect('Outlook.Application') 
    WIN32OLE.const_load($outlook,OutlookConst)
    $namespaceOutlook=$outlook.GetNamespace("MAPI")
    $topFolder=$namespaceOutlook.Folders.Item('heinz.breinlinger@allianz.de')
    sender.gsub!(/dr\.\s*/i,"")  # Akademischen Grad loeschen
    planviewFolder=$topFolder.Folders.Item($planviewFolderName)
    archiveFolder=planviewFolder.Folders.Item($archiveFolderName)
    archiveFolder.Items.each{ |mail|
      subject=mail.Subject
      (! subject.match(/#{$keyWord}/)) && die("outlook2Config: Betreff #{subject} enthaelt Begriff #{$keyWord} nicht")
      sender=mail.SenderName
      ...
    maskArr=subject.scan(/[0-9]{4}/)
    #---------------------------------------------------------------
    calendar.Items.each{ |appointment|
      i+=1
      if(appointment.entryID == entryID)
        return appointment
      end
    }
    #---------------------------------------------------------------
    mail=sourceFolder.Items.GetFirst
    mail.Move(targetFolder)
    #---------------------------------------------------------------
    while(planviewFolder.Items.Count != 0) do
      mail=planviewFolder.Items.GetFirst
      printf("Verschiebe %s in Ordner %s\n",mail.SenderName,$doneFolderName)
      mail.Move(doneFolder)
    end

  IE/Edge
  =========
    $ie=WIN32OLE.new('InternetExplorer.Application'); checkValue($ie)
    $ie.visible=true

  Excel
  =====
    #---------------------------------------------------------------
    sheet.Range("A1:C10").Clear
    sheet.Range("A1:C10").ClearContents
    book.worksheets(sheetNum).Cells.ClearContents
    #---------------------------------------------------------------
    book=$excel.Workbooks.add
    sheet=book.Worksheets.add
    #---------------------------------------------------------------
    percFormat="0,00%"
    currFormat="#.##0,00 \"Eur\";[Rot]-#.##0,00 \"Eur\""
    floatFormat="#.##0,00;[Rot]-#.##0,00"
    intFormat="#.##0;[Rot]-#.##0"
    dateFormat="TT.MM.JJ"
    timeFormat="hh:mm:ss"
    sheet.cells(row,col).numberFormat=currFormat
    sheet.range("A2:F60").numberFormat=currFormat
    sheet.range("A"+row.to_s+":F"+row.to_s).horizontalAlignment=ExcelConst::XlCenter (..XlLeft ..XlRight)
    #---------------------------------------------------------------
    # Konvertierung
    #---------------------------------------------------------------
    book=$excel.Workbooks.Open(qualFile); checkValue(book)
    book.saveAs(qualNewFile,ExcelConst::XlOpenXMLWorkbook)
    book.close
    #---------------------------------------------------------------
    $excel=WIN32OLE.connect('Excel.Application') 
    $excel=WIN32OLE.new('Excel.Application'); checkValue($excel)
    $excel.DisplayAlerts=false                  # verhindert Schlussfrage, ob gespeichert werden soll
    WIN32OLE.const_load($excel,ExcelConst)
    #---------------------------------------------------------------
    book=$excel.Workbooks.Open(file); checkValue(book)
    (1..book.worksheets.count).each{ |i|
      sheetName=book.worksheets(i).Name
      if(sheetName.match(/^#{name}/i))
        ...
    #---------------------------------------------------------------
    book=$excel.Workbooks.Open(file); checkValue(book)
    book.worksheets(sheetNum).Activate 
    sheetName=book.worksheets(sheetNum).Name
    book.saveAs(csvFile,ExcelConst::XlCSV) # alternativ: ExcelConst::XlCSVWindows|XlCSVMSDOS
    book.close
    #---------------------------------------------------------------
    numSheets=book.worksheets.count
    #---------------------------------------------------------------
    # Zellformat-Wandlung
    #
    # "a4" => 4,1
    #------------------------------------------------------------
    (! cell.match(/^[[:alnum:]]+$/)) && die("excelExtractFromFile: Falsches Zellenformat 1: #{cell}")
    (! cell.match(/^([[:alpha:]]+)([[:digit:]]+)$/)) && die("excelExtractFromFile: Falsches Zellenformat 2: #{cell}")
    column=$1.upcase # "A"
    row=$2           # "4"
    (! $excelColumnMapReverse.key?(column)) && die("excelExtractFromFile: Spalte #{column} ist nicht in Mapping-Tabelle enthalten")
    column=$excelColumnMapReverse[column]
    row=row.to_i
    column=column.to_i
    text=book.worksheets(sheetNum).cells(row,column).Value.to_s # String-Wandlung
    text=sheetNum.to_s+":"+cell.to_s+":"+text.encode!("ISO-8859-1")
    #------------------------------------------------------------
    book.worksheets(sheetNum).cells(row,column).Value=text
    #------------------------------------------------------------
    $excel.quit()
    #------------------------------------------------------------
    result=%x(tasklist /FI "IMAGENAME eq #{process}" /FI "PID ne #{$$}")
    #------------------------------------------------------------
    delete && sheet.Hyperlinks.Delete()
    colChar=$excelColumnMap[col]
    sheet.Hyperlinks.Add(sheet.Range(colChar+row.to_s),demandUrl,"",mouseOver,displayText)
    sheet.Range(colChar+row.to_s).NumberFormat="@"
    sheet.Range("A"+i.to_s+":Z"+i.to_s).Font.Size=8
    sheet.Range("C"+i.to_s+":C"+i.to_s).NumberFormat="#,## \" %\"" 
    sheet.cells(row,col).Value=cellContent.to_s
    #- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
    sheet.Columns("A:Z").Autofit
    $excel.activeWindow.DisplayZeros=0
    book.SaveAs(fileName+".xlsx") 
    book.ExportAsFixedFormat(ExcelConst::XlTypePDF,fileName+".pdf",nil,true)  # true ist "IgnorePrintAreas"
    book.Close
    #- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
    sheet=book.worksheets(1); checkValue(sheet)
    #------------------------------------------------------------------------------------------------------------------------------------------------
    book=$excel.Workbooks.Add; checkValue(book)
    sheet=book.Worksheets.Add; checkValue(sheet)
    sheet.Name="Anthologie"
    sheet.Tab.Color=rgb(61,163,95)
    sheet.Range("C2:D10000").NumberFormat="##.# \" Eur\"" 
    sheet.Range("A"+row.to_s+":D"+row.to_s).Interior.ColorIndex=40
    sheet.Range(3,8).Font.ColorIndex=6 # gelb
    sheet.Range("A1:J2").Font.Bold=1
    sheet.Range("A1:A10000").Autofilter(1,["Nova","Team"],ExcelConst::XlFilterValues) 
    sheet.Columns("A:Z").Autofit
    $excel.activeWindow.DisplayZeros=0
    #---------------------------------------------
    # Standardtabellenblaetter loeschen
    #---------------------------------------------
    1.upto(1){ |i|
      sheet=book.Worksheets("Tabelle"+i.to_s)
      sheet=book.worksheets("Referat"); checkValue(sheet)
      if(sheet)
        sheet.Delete
      end
    }
    book.Worksheets(1).Activate
    #---------------------------------------------
    comment=sheet.Range("I1:I1").AddComment
    comment.Text("Fuer erweitere Ansicht in Spalte A \"Resource\" anhaken")
    comment.Shape.TextFrame.AutoSize=true
    comment.Visible=true
    range=sheet.Range(sonstIstColChar+row.to_s)
    range.Comment && range.Comment.Delete
    #---------------------------------------------
    def makeComment(cell,comment)
      shape=cell.AddComment(comment).Shape
      shape.Width=400
      shape.Height=100
    end
    #---------------------------------------------
    sheet.Range("A1:J1").Font.Bold=1
    sheet.Range("A2:H2").Interior.ColorIndex=50
    sheet.Range("A3:H3").Interior.ColorIndex=44
    sheet.Range("C2").NumberFormat="# \" Tage\"" 
    sheet.Range("C3:D1000").NumberFormat="##.# \" Eur\"" 
    sheet.Range("E1:E1000").NumberFormat="#,## \" %\"" 
    sheet.Range("F3:F1000").NumberFormat="[Rot]##.# \" Eur\";[Farbe10]-##.# \" Eur\"" 
    sheet.Range("G3:G1000").NumberFormat="##.# \" Eur\"" 
    sheet.Range("H3:H1000").NumberFormat="[Rot]##.# \" Eur\";[Farbe10]-##.# \" Eur\"" 
    sheet.Range("A1:A1000").Autofilter(1,["Zeit","Projekt","Team"],ExcelConst::XlFilterValues) 
    sheet.Range("A"+row.to_s+":M"+row.to_s).Font.Bold=1
    sheet.Range("A"+row.to_s+":M"+row.to_s).Borders(ExcelConst::XlEdgeBottom).LineStyle=ExcelConst::XlContinuous
    sheet.Range("A"+row.to_s+":M"+row.to_s).Borders(ExcelConst::XlEdgeBottom).weight=ExcelConst::XlThin
    sheet.Range("A"+row.to_s+":M"+row.to_s).Borders(ExcelConst::XlEdgeBottom).weight=ExcelConst::XlMedium
    sheet.Range("A"+row.to_s+":M"+row.to_s).Borders(ExcelConst::XlEdgeBottom).ColorIndex=ExcelConst::XlAutomatic
    sheet.Columns("A:Z").Autofit
    $excel.activeWindow.SplitColumn=0
    $excel.activeWindow.SplitRow=3
    $excel.activeWindow.freezepanes=1 # Cave: Excel muss maximiert geoeffnet sein
    $excel.activeWindow.DisplayZeros=0
    sheet.Range("A1:M1").Autofilter
    sheet.Columns("A:M").AutoFit
    sheet.Columns("C:L").NumberFormat="0,0"
    sheet.Range("A2").Select
    $excel.activeWindow.freezepanes=1
    $excel.activeWindow.DisplayZeros=0
    book.SaveAs(Dir.getwd+"/Synopse.xls")
    book.Close
    #---------------------------------------------
    #- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    # Rest-Formatierungen
    #- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    sheet.Range("A1:J1").Font.Bold=1
    sheet.Range("A2:H2").Interior.ColorIndex=50
    sheet.Range("A3:H3").Interior.ColorIndex=44
    sheet.Range("C2").NumberFormat="# \" Tage\"" 
    sheet.Range("E1:E1000").NumberFormat="#,## \" %\"" 
    sheet.Range("F3:F1000").NumberFormat="[Rot]##.# \" Eur\";[Farbe10]-##.# \" Eur\"" 
    sheet.Range("G3:G1000").NumberFormat="##.# \" Eur\"" 
    sheet.Range("H3:H1000").NumberFormat="[Rot]##.# \" Eur\";[Farbe10]-##.# \" Eur\"" 
    #-----------------------------------------------------------------
    sheet.Range("A2").Select
    $excel.ActiveWindow.FreezePanes=true
    sheet.Columns("A:AZ").Autofit
    sheet.Range("A2:AZ1000").Sort({"Key1" => sheet.Range("B2:B1000")})
    #-----------------------------------------------------------------
    sheet.Range("A1:Z1").Autofilter
    sheet.Columns("A:Z").Autofit
    sheet.Range("A1:Z1").Font.Bold=1
    $excel.ActiveWindow.SplitColumn=0
    $excel.ActiveWindow.SplitRow=1
    $excel.ActiveWindow.FreezePanes=1
    #- - - - - - - - - - - - - - - - - - - - - - -
    # Blatt ans Ende stellen
    #   'nil' ist der 'before'-Parameter von sheet.Move
    #   der zweite Parameter ist 'after'
    #- - - - - - - - - - - - - - - - - - - - - - -
    sheet.Move(nil,book.Worksheets(2)) # Sheet "Linie" ist Nummer 2, da "Team" davor als Nummer 1 gesetzt wurde
    #- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    # Querformat fuer PDF-Export
    #- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    if($pdfExport)
      sheet.PageSetup.Orientation=ExcelConst::XlLandscape 
      sheet.PageSetup.PrintArea="A1:H#{PRINTAREAROW}"
    end
    #- - - - - - - - - - - - - - - - - - - - - - -
    # Standardtabellenblaetter loeschen
    #- - - - - - - - - - - - - - - - - - - - - - -
    1.upto(1){ |i|
      sheet=book.Worksheets("Tabelle"+i.to_s)
      if(sheet)
        sheet.Delete
      end
    }
    #- - - - - - - - - - - - - - - - - - - - - - -
    # Sheet "Linie" aktivieren
    #- - - - - - - - - - - - - - - - - - - - - - -
    book.Worksheets(1).Activate
    #- - - - - - - - - - - - - - - - - - - - - - -
    book.SaveAs($cwd+"\\"+scope+"_"+$projName+".xlsx") 
    #- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    # PDF-Export der Datei, d.h. beider Sheets
    #- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    if($pdfExport)
      book.ExportAsFixedFormat(ExcelConst::XlTypePDF,$cwd+"\\"+scope+"_"+$projName+".pdf",nil,true)  # true ist "IgnorePrintAreas"
    end
    #-----------------------------------------------------------------
    rangeVist=sheet.Range(vistColChar+row.to_s)
    #-----------------------------------------------------------------
    #- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    # Cave: Hier muss die Blockform von "sub!" verwendet werden, da
    # die Backreference $1 erst NACH Abschluss des Patternmatch gesetzt wird.
    #- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
    budget2=(tage*tagessatz).to_s
      .sub!(/\./,",")               # "." durch "," ersetzen
      .sub!(/,(\d)$/) do            # Bei einer Nachkommastelle "0" anhaengen
        ",#{$1}0"
      end
      .sub!(/(\d)(\d{3},)/) do      # Tausendertrennzeichen "." setzen
        "#{$1}.#{$2}"
      end

  Word
  ====
    #---------------------------------------------------------------
    doc=$word.Documents.Open(qualFile); checkValue(doc)
    doc.saveAs2(qualNewFile,WordConst::WdFormatDocumentDefault)
    doc.close
    $word.quit()
    #---------------------------------------------------------------
    $word=WIN32OLE.connect('Word.Application'); checkValue($word)
    $word=WIN32OLE.new('Word.Application'); checkValue($word); checkValue($word)
    $word.Visible=1
    $word.DisplayAlerts=false # verhindert Schlussfrage, ob gespeichert werden soll
    WIN32OLE.const_load($word,WordConst)
    #------------------------------------------------------------
    if(replaceAll)
      modifier=WordConst::WdReplaceAll
      kind="alle Vorkommen"
    else
      modifier=WordConst::WdReplaceOne
      kind="erstes Vorkommen"
    end
    content=doc.Content
    find=content.find
    #------------------------------------------------------------
    doc=$word.Documents.Open(cwd+"/"+file); checkValue(doc)
    text=doc.Range.Text
    #- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
    # cf. https://docs.microsoft.com/en-us/office/vba/api/word.find.execute
    # cf. in Word (Ctrl-h) die korrespondierenden Suchen- und Ersetzen-Parameter
    #
    # 1. FindText
    # 2. MatchCase true
    # 3. MatchWholeWord true
    # 4. MatchWildCards false
    # 5. MatchSoundsLike false
    # 6. MatchAllWordForms false
    # 7. Forward true
    # 8. Wrap (am Dokumentende fortfahren)
    # 9. Format false (Formatierung ist kein Kriterium)
    # 10. ReplaceWith (Ersetzungs-String)
    # 11. Replace wdReplaceAll (wdReplaceOne, wdReplaceNone)
    # 12-15 vermutlich 4 aus: MatchPrefix, MatchSuffix, MatchPhrase, IgnoreSpace, IgnorePunct (nicht MatchKashida, MatchDicritics,
    #       MatchAlefHamza, MatchControl)
    #
    #             1       2    3    4     5      6    7    8                         9     10      11                      12-15
    #- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
    find.execute(toReplace,true,true,false,false,false,true,WordConst::WdFindContinue,false,replacement,modifier,false,false,false,false)
    if(find.found)
      ...
    doc.saveAs2($confDir+"\\"+$lbHash[VERTRAG]+"_Leistungsbeschreibung.docx")

Impressum und Datenschutzerklärung