Meine persönlichen Gedächtnisstützen der wichtigsten Werkzeuge ...
shopt -s extglob shopt -u extglob shopt -s globstar ls **/*.jpg # Suche (auch) in Unterverzeichnissen shopt -s dotglob ls * # Anzeige (auch) versteckter Dateien (sonst ls .* noetig) shopt -s nocaseglob Reihenfolge =========== tilde-expansion variable-substitution command-substitution arithmetic expression word splitting of expanded text wildcard expansion command-lookup ( expression ) # returns the value of expression (cf. files=(*) ) # This does NOT work in the general case $ files=$(ls ~/*.jpg); cp $files /backups/ <= Whitespace in Dateinamen moeglich # # This DOES work in the general case $ files=(~/*.jpg); cp "${files[@]}" /backups/ <= 1.) globbing und 2.) escaped Array bewahren White-Spaces in Dateinamen $ files=$(ls) # BAD, BAD, BAD! <= Whitespace in Dateinamen $ files=($(ls)) # STILL BAD! $ files=(*) # Good! <= Globbing bewahrt White-Space 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 "|%*.*s|\n" 3 3 willi # => |wil| printf "%x %X" 15 15 # f F ========================================= Dezimale, oktale und hexadezimale Ausgabe ========================================= Hex => Oct printf "%o\n" 0x3a # => : Oct => Hex printf "%x\n" \072 # => 3a Octalwert MUSS 3-stellig sein Oct => Dec printf "%d\n" \072 # => 58 Oct => Char echo $'\72' # => : Octalwert darf 1- bis 3-stellig sein (octal 72 == dezimal: 58) echo $'\072' # => : Hex => Char echo $'\x3a' # => : (hexadezimal x3a == dezimal: 58) Octal printf "\033" # => ESC Screen als Canvas ========================================= printf "\033[%d;%dH" 10 10 # => Cursor an Position 10/10 echo "Hello" alternativ cursMov=$'\e[%d;%dH' # \e == \033 printf "$cursMov" 10 10 echo "Hello" -------------------------------------------------------------------------- #!/bin/bash # Variante 1: Escape-Sequences : <<EOF cu_row_col=$'\e[%d;%dH' cu_row_col=$'\033[%d;%dH' printf "$cu_row_col" ${2:-0} ${3:-0} # printf "\033[%d;%dH" 5 10 echo "${1?}" EOF # Alternative: tput # tput setab 1 # tput setaf 2 tput cup ${2:-0} ${3:-0} echo "${1?}" -------------------------------------------------------------------------- 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" (=> 5 zeigt auf aktuelle Fehlerausgabe) exec 2> /tmp/hugo # Fehlerausgabe aendern exec 2>&5 # Fehlerausgabe "zuruecksichern" (2 zeigt auf aktuelles 5 == frueheres 2) exec 5>&- # Sicherung loeschen (implizit 5 von 2 loesen) #------------------------- read a b c d # $d beinhaltet Rest der commandline date=$(date) # == date=`date` [ ] # == test (builtin command (strings, integers und Dateiattribute), word splitting und file name expansion) [ "$var" -eq 0 ] [ "$str" != "string" ] [ -z "$str" ] [[ ]] # test inkl. regular expressions (not builtin command => parameter expansion ohne word spliting und file name expansion) file="file name" # now word splitting [[ -f $file ]] && echo "..." [[ -f $file1 && ( -d $dir1 || -d $dir2 ) ]] # Escape fuer Klammern nicht noetig [ -f "$file1" -a \( -d "$dir1" -o -d "$dir2" \) ] [[ "$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)th?o ]] # 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 != ist Negation zu =, == shopt -s extglob [[ "$hugo" != +([0-9]) ]] # Keine Zahlen 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") shopt -s extglob echo ${*%%*(.gif|.jpg|.png)} shopt -s extglob array=($*) # Cave: Trennung bei Whitespace innerhalb von Elementen aus $* echo ${array[*]%%*(.gif|.jpg|.png)} #--------------------------------------------------------------------------------------------------------------------- shopt -s extglob pattern=0.00000 # 5 Nachkommastellen case $pattern in *0[.]00000*([^0])) echo "Fein" ;; # Test auf nicht mehr als 5 Nachkommanullen *) echo "Unfein" ;; esac #--------------------------------------------------------------------------------------------------------------------- datum=01.01.2022 datum=2022.01.01 datum=01.01.22 datum=22.01.01 if [[ "$datum" =~ ^[0-9]{2,4}[^0-9][0-9]{2}[^0-9][0-9]{2,4}$ ]]; then printf "Fein\n" else printf "Unfein\n" fi #---------------------------------------- # 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 Anweisung ist Schleifenbedingung echo "i: $i ($max)" 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 #---------------------------------------- ((...)) oder $((...)) # $((...)) Posix ... ((...)) nicht Posix if ((flag)); then ...; fi # Integer als true/false (( var )) && ... # Test auf non-zero test $(( a - 2 )) -ne 0 # Arithmetik: Variablen muessen nicht dereferenziert werden ((abs = (a >= 0) ? a : -a)) # Ternary verfuegbar let a='(5+2)*3' # bei 'let' Klammern quoten for ((i=1; i<=$1; i++)); do echo $i; done if (( total > max )); then # da kein builtin sondern shell-syntax, werden '<>' nicht als redirection interpretiert Listen: # Exit-code = Exit-code des letzten statements <command>;<command>;... <command> && <command> ... grep -q goodword "$file" && ! grep -q badword "$file" && rm "$file" grep -q goodword "$file" && ! grep -q badword "$file" && { rm "$file" || echo "Couldn't delete: $file" >&2; } # Cave: Semikolon vor schliessender Klammer <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 || { ... } Command-Group { ls ...; cd ...; cat ...; } >out 2>&1 # Cave: ';' auch nach letztem (!) Kommando, sonst wird '}' als Argument desselben interpretiert [[ -f $CONFIGFILE ]] || { echo "Config file $CONFIGFILE not found" >&2; exit 1; } # Cave: 'exit 1' wuerde in Subshell nicht die aufrufende Shell beenden { read firstLine read secondLine while read otherLine; do something done } < file 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 file=${file//+( )/_} # shopt -s extglob: Alle Blankfolgen durch '_' ersetzen printf "%s\n" ${passwd/[[:upper:]]/*} # Ersetzung des ersten Grossbuchstabens ${var:2:2} # offset und length Pruefung von Variablen ========================================= Falls in "prog": var={1:?} dann ./prog "" # 1: Parameter ist Null oder nicht gesetzt ./prog # 1: Parameter ist Null oder nicht gesetzt Falls in "prog": var={1?} dann ./prog "" # <alles ok> ./prog # 1: Der Parameter ist nicht gesetzt #--------------------------------- # 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 #--------------------------------- while IFS=':' read file category; do # Assoziativer Array eines dynamischen Arrays if [[ ! "${catA[*]}" =~ "$category" ]]; then # Array to String => Test auf Membership (String( nicht Pattern-)-Match auf Teilstring) catA+=( "$category" ) fi eval ${category}+=\( \$file \) # dynamischer Array (Name resultiert aus Variable) fileA+=( $file ) done < "$config" #- - - - - - - - - - - - - - - - - for category in "${catA[@]}"; do eval array=( \"\${${category}[@]}\" ) # String to Array for file in "${array[@]}"; do printf "%20.20s => %s\n" "$category" "$file" done 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[@]:1}" # Alle Array-Elemente ab dem zweiten 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 #------------------------- while read line; do # Erst nach Einlesen der Zeile IFS veraendern ... IFS=\; set -- $line echo "$1 - $2 - $3" IFS=$'{ \t\n}' # und restaurieren done < Hugo #------------------------- cat a.txt | tr 'aeiou' 'AEIOU' > out.txt #------------------------- { # Gruppierung (nicht Sub-Shell) date cat report.txt } | mail -s "Hugo" name@adress #------------------------- IFS=. read -ra ip_elements <<< "127.0.0.1" # Here-String als Standardeingabe (Manual: "The word is expanded and supplied to the command on its standard input.") #------------------------- files=file1,file2,file3,file4 mapfile -t -d ',' filesArr <<< "$files" # Cave: Here-String => haengt am "Dateiende", damit an file4 ein Newline an => mapfile -t -d ',' filesArr < <(echo -n "$files") # besser: Ausgabe ohne Newline #------------------------- if grep -q "txt" <<< "$VAR" # Here-String wird zu Standardeingabe then echo "$VAR contains the substring sequence \"txt\"" fi while read element ; do echo "$element" 1>&2 done <<< $(echo ${ArrayVar[*]}) # Here-String #------------------------- { # 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 #------------------------- string="hugo:willi:franz" read -a array -d ':' <<< "$string" # -d: read up to delimiter printf "%s\n" "${array[@]}" => hugo #------------------------- select name in Hugo Franz Willi Exit; do case $name in Hugo) echo "..." ;; Franz) ... ;; Willi) ... ;; Exit) exit 0 ;; *) echo "Ungueltige Auswahl" ;; esac done #------------------------- 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 if [ "$a" = a ] || { [ "$b" = b ] && [ "$c" = c ];}; then ... grouping mit abschliessendem ';' <= ';' wird sonst als Argument interpretiert #------------------------- 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]/A} --------------------------------------------------------------------------------------- Match-Groups ------------ string=franz_hugo_willi [[ $string =~ (fritz|h(ug|ag)o)_willi ]] # extended regular expression (man regex 3) echo ${BASH_REMATCH[@]} => hugo_willi hugo ug --------------------------------------------------------------------------------------- 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 names=([0]="Bob" [1]="Peter" [20]="$USER" [21]="Big Bad John") # sparse array photos=(~/"My Photos"/*.jpg) # globbing => array # nicht Aufloesung eines Ausdruckes: ( expression ) returns the value of expression 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 # Anstelle IFS zu aendern, explizit einen delimiter setzen file ---- Hugo|Franz|Willi Markus|Dieter|Franz mapfile -d '|' -t < file printf "%s\n" "${MAPFILE[@]}" Hugo Franz Willi .... ------------------------------------------------------------------------------------------ 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 ------------------------------------------------------------------------------------------ # command expansion mit awk ------------------------------------------------------------------------------------------ colLen=$(awk -F ';' ' BEGIN{ for(i=1;i<=130;i++){ colLen[i]=0; OFS=";"; rightMostCol=0; } } { #---------------------------------------------------------------------------- # Maximale Feldzahl aktualieren #---------------------------------------------------------------------------- if(NF > rightMostCol){ rightMostCol=NF; } #---------------------------------------------------------------------------- # Spaltenbreiten bestimmen #---------------------------------------------------------------------------- for(i=1;i<=NF;i++){ #-------------------------------------------------------------------------- len=length($i); if(len > colLen[i]){ colLen[i]=len; } } } END{ for(i=1;i<=rightMostCol;i++){ printf(" %s",colLen[i]); } } ' dummy.csv) printf "Laenge: %s\n" "$colLen" #------------------------------------------------------------------------------------- # URL-encoded String dekodieren # Hexadezimal 21 ist '!' #------------------------------------------------------------------------------------- echo 'a%21b' | while read; do echo -e ${REPLY//%/\\x}; done # Alle mit % gekennzeichnenten Hexadezimalkodierungen durch Hex-Prefix kennzeichnen und damit implit dekodieren while read; do : "${REPLY//%/\\x}" echo -e ${_//+/ } # Whitespace ist mit '+' URL-codiert done : is a BASH builtin command. Here it just takes in a single argument and does nothing with it. The double quotes make everything inside one single parameter. _ is a special parameter that is equal to the last argument of the previous command, after argument expansion. This is the value of REPLY with all instances of '%' replaced with '\x'. ${_//+/ } replaces all instances of '+' with ' '. #-------------------------------------------------------------------------------------
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 - Folding Interaktiv V (Visual) + <move> zf Ein Fold zo (open) zc (close) zf (create) zd (delete) Mehrere Folds zO (alle unterhalb Cursor oeffnen) zC (alle unter Cursor schliessen) zR (alle oeffnen) zM (alle schliessen) zD (alle unterhalb Cursor loeschen) zE alle Folds loeschen :1,5 fo(ld) :set foldmedthod = marker,manual,indent,syntax, ... :set foldmarker={{{{,}}}} Ansicht mit (manuell angelegten) Folds speichern :mkview Ansicht mit Folds laden :loadview - Kleinbefehle . letzten Befehl wiederholen 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 z10l z10h Bildschirm 10 Zeichen nach links/rechts zH halben Bildschirm nach rechts z10h 10 Spalten nach rechts zL halben Bildschirm nach links z17l 17 Spalten nach links Bildschirmspruenge H (igh) M (iddle) L (ow) 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 80| => Springe zu Spalte 80 g0 Im folgenden sind '/' und '?' fuer Vorwaerts/Rueckwaerts austauschbar --------------------------------------------------------------------- d/Hugo (Loesche bis Hugo) c/Willi (Aendere bis Willi) y/Franz (Kopiere bis Franz) y?a (Kopiere rueckwaerts bis einschliesslich a) 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) "_daw Aktuelles Wort in "blackhole" register speichern (== Loeschen ohne undo/redo) '_' ist blackhole-register "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) % (Sprung zu korrespondierendem Klammerpaar) 0,$ (zu Zeilenanfang/-ende) _ oder ^ (zu erstem Zeichen der Zeile) 3yb oder y3b (3 Worte zurueck kopieren) 5yl oder y5l (5 Zeichen zurueck kopieren) 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 ------------------------- g-Ctrl-a Ctrl-a inkrementiert die erste Zahl einer Zeile Dies gilt auch in einem Mit Shift-v gewaehlten Bereich mit Modifier 'g' davor werden alle ersten Zahlen des Bereiches zum jeweils vorherigen, um 1 inkrementierten Wert ! 1 => 2 1 => 3 1 => 4 1 => 5 1 => 6 gj,gk,g0,g$ (Navigation nicht nach Editor-, sondern Bildschirmzeilen) gUiW (Uppercase inside Word (non-whitespace)) gUE (Grosschreibung bis Wortende (non-whitespace)) gue (Kleinschreibung bis Wortende) gUge (Grosschreibung zurueck bis Ende des letzten Wortes) guG (lowercase bis zum Ende des Dokumentes) gUG (uppercase ...) - 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 gR (virtual replace mode => Tab als Folge von Blanks interpretieren) ~ Case-Wechsel 30~ Case-Wechsel der naechsten 30 Zeichen > oder < oder = Ctrl-o und Ctrl-i (zwischen letzten Sprungmarken vor- und zuruecknavigieren) S. 138 "Practical Vim" :set suffixesadd+=.rb (.rb in Liste automatischer Suffix-Ergaenzungen aufnehmen) falls Cursor auf Dateiname steht, z.B. file gf => Oeffne file.rb (Mnemo: goto file, real g (== modify Folge-)Befehl f (== find) zu Datei anstelle Zeichen in Zeile) Ctrl-o => Ruecksprung zu voriger Datei (aus welcher Absprung erfolgte) "ac2w (naechste 2 Worte aendern und Original in Register a) Visual Mode zeichenweise v viw (visual inside word) vaW (visual around non-whitespace) 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)) gv (modified v): markiert zuletzt markierten Bereich erneut 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 / letztes Suchfeld ausgeben Ctrl-r Ctrl-p 0 (dito, jedoch ohne Einrueckungen) Ctrl-r " unnamed register ausgeben Ctrl-r = 20 * 5 (Rechenergebnis einfuegen == numerisches Register ausgeben) 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) Markieren ma 'a `a `` Rueckkehr zu vorigem Absprungpunkt (Auto-Sprungmarke) '' Rueckkehr zu voriger Absprungzeile (Auto-Sprungmarke) mA Grossbuchstaben => Datei-uebergreifend == global mark - 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$ 2D 2 Zeilen loeschen Y (bezieht sich auf ganze Zeile) 10Y 10 Zeilen kopieren S (bezieht sich auf ganze Zeile) 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 :s/Hugo/Willi/gc => falls nun Ersetzung fuer ALLE Zeilen gewuenscht :%s//~/& Ersetzung des letzten Suchmusters duch letztes Ersetzungsmuster mit denselben Flags wie zuvor g& Kurzform des vorigen ("global alles gleich" oder "modifiziert dasselbe") :s/Hugo/Willi :& Wiederholung der letzten Substitution (fuer nun aktuelle Zeile), jedoch nicht den letzte Flags g& Wiederholung der letzten Substitution fuer alle Zeilen :&& Wiederholung der letzten Substitution mit den letzten Flags :vimgrep /hugo/g *.rb Suche in allen *.rb-Dateien (und Editierung der Treffer) :set (no)hlsearch Highlighting fuer Suchergebnisse an/aus :set (no)hls /,? /Hugo/e Cursor auf Ende des Treffers positionieren n,N gn,gN visual mode fuer naechsten Treffer :%s/Burg/Berge/g /~ (Tilde ist letzter Ersetzungsusdruck) => Suche nach Berge :cnext naechster und :cprev vorheriger Treffer 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 :s/Willi/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 (Aufzeichnung beenden) => qaq (Register a loeschen) @a 4@a (Makro aus a 4 mal anwenden) @@ (letztes Makro anwenden) Ctrl-V <move>:normal @a (aus Visual-Mode in ex-mode und fuer markierten Bereich Makro aus a ausfuehren) auf diese Weise kann alternativ zu Ctrl-v spaltenweise editiert werden, indem die Editierung des Feldes in Spalte 1 aufgezeichnet und danach fuer weitere Zeilen wiederholt wird. - 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 jeweiligen 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 :edit! Datei neu editieren, alle Aenderungen implizit verwerfen, :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 == History) Ctrl-z (Stop und Shell aufrufen => Beenden/Rueckkehr mit fg) dito :stop => wie Ctrl-Z :!ls :r!ls (Ausgabe von ls unterhalb Cursor einlesen) :7r!ls (dito unterhalb Zeile 7) :$!uptime (letzte Zeile durch Laufzeit ersetzen) :10,20! sort -t',' -k2 :source hugo.vim (wenn hugo.vim ex-Befehle enthaelt) :buffers :jumps (=> Jump-List) :changes (=> Change-List) :w >> bestehende_Datei :w %.new (Speichern in <aktuelle Datei>.new) Auch Datei-uebergreifend kopieren :10,20yank a <Datei-Wechsel> "ap :bnext,bprevious,bfirst,blast,bdelete (Nummer oder Name) :3,5 bdelete :buffer 2 Wechsel zu Buffer 1 (== zweiter editierter Datei) :n(ext) (naechste Datei editieren) :1,10# (Zeilennummer temporaer einblenden) :put (paste immer UNTER die aktuelle Zeile im Unterschied zu p !) :args :args *.rb (befuellt die Argument-Liste <=> Buffer-Liste jedoch davon unbeeinflusst) => nun moeglich :next :prev :first :last :argdo :qa(ll)! :wa(ll)! :argdo normal @a fuer alle Elemente der Argument-Liste Makro a ausfuehren :argdo write (== :wa) :e(dit)! Datei neu einlesen (== Aenderungen verwerfen) :e Hugo.txt (weitere Datei editieren) % ist aktuelle Datei # ist alternative Datei :buffer# (Wechsel zur jeweils anderen Datei) :r# Zweite Datei in erste einlesen Autocompletion ============== Ctrl-n Autocompletion aus generic wordlist CTRL-x (gefolgt von CTRL-...) cf. Pocket Reference Seite 47 Auswahl mit CTRL-n/-p/-y Abbuch mit CTRL-e (end) ... CTRL-n/-p Suche in mit 'complete' festgelegten Quellen complete-List: .,w,b,u,t,i d.h. effektiv in vorherigen oder folgenden Zeilen des aktuellen Buffers "." ... CTRL-f Autocompletion von Dateien mit Auswahl (in Insert-Mode) ... CTRL-d Macros ... CTRL-k Dictionary (nach via 'dictionary' festgelegter Liste) In .vimrc: set complete+=k Autovervollstaendigung auch innerhalb von dictionaries (zusaetzlich zu ".,w,b,u,t,i") set dictionary+=~/.vim/teams.dict ... CTRL-l Zeile in vorherigem Text derselben Datei ... CTRL-s Spelling, sofern 'spell' gesetzt ist ... CTRL-t Thesaurus via 'thesaurus' Hugo Ctrl-X <Tab> Suche in Wortliste der aktuellen Datei nach Worten, welche mit Hugo beginnen fuer autocomplete Ctrl-n (next) Ctrl-p (previous) Ctrl-y (yes) Ctrl-e (end ohne Uebernahme) Trick: Ctrl-x Ctrl-k Aufruf der Autocomplete-Liste Ctrl-p Sprung eine Zeile vor erstem Element == aktuell editierte Zeile alternativ fuer Autocomplete-Liste des aktuellen Buffers anstelle des Dictionaries Ctrl-x Ctrl-n Ctrl-p => Sprung ueber Liste (== editierte Zeile) Ctrl-x Ctrl-p Ctrl-n => Sprung unter Liste (== editierte Zeile) Hugo => Autofilerung der angezeigten Liste nach allen mit 'Hugo' beginnenden Eintraegen => Eingabe mit fortlaufend aktualisiertem Autocomplete cf. S. 238 "Practical Vim" Filename-completion :pwd => aktuelles Verzeichnis :cd /usr/local/bin i my Ctrl-x Ctrl-f => Dateiliste aus /usr/local/bin zur Auswahl fuer alle mit 'my' beginnenden Dateien :cd - => Rueckkehr zu urspruenglichem Verzeichnis (des aktuellen Buffers) analog 'cd -' in Shell (=> vorheriges Verzeichnis) :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 gt,gT,1gt,tabs,tabm 0 :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,20t17 :10,20m. (move statt copy) :17,19d :5,25 normal A; (am Zeilenende ';' anfuegen) :%normal yi"$p (Kopiere in allen Zeilen innerhalb '"' und gib an Zeilenende aus) :% normal i// (Allen Zeilen "//" vornstellen) :5,25g/Hugo/normal @a (Macro aus Register a auf Zeilen in Range 5-25, welche Hugo beinhalten, anwenden) :v/href/d (reziprokes global: Alle Zeilen loeschen, welche nicht href beinhalten ) :%s/Hugo/Willi/g :/<Start>/+1,/<End>/-1d (Zeilen zwischen Mustern loeschen) :'<,'> Range bei visueller Auswahl :.,.+3p aktuelle und 3 Folge-Zeilen ausgeben :'as/Hugo/Willi/g in Range mit Markierung 'a' substituieren :5co0 (0 ist virtuelle Zeile oberhalb Datei => An Anfang kopieren) :'<'>t0 (Range an Anfang kopieren) :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 Beispiel: Ersetzen eines 1000-Trennpunktes :%s/\v([0-9]+)\.([0-9]{3})/\1\2/g :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([a-z]+)/"\1"/g (Alle Worte in '"' setzen) :%s/\V ... (very non-magic) "uY Zeile in Register u speichern /\VCtrl-ru non-magic-Suche nach Inhalt von Register u :%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 => alle nicht dem vorigen Suchmuster entsprechenden Zeilen loeschen :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) Fuer jede Zeile mit "{": Sortiere von "aktueller Zeile + 1" bis eine Zeile vor "}" :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 Quantifier (fuer nicht very-magic) \+ (1 oder mehrere) \= (0 oder 1) \{1,4\} (1 bis 4} 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 Fenster per Maus zu aktivieren) :set iskeyword? Werteliste fuer iskeyword anzeigen :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 Hoehe 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) :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-r ====== Insert-Mode: Ctrl-r<register> Register einfuegen Ctrl-r / letztes Suchfeld ausgeben Ex-Mode :Ctrl-ra (Register a auf Command-Line einfuegen) :Ctrl-r / letztes Suchfeld ausgeben "ayw yank word in Register a :%s/Ctrl-ra/Hugo/g Ersetze Inhalt von Register ueberall global Ctrl-r= 10 * 20 (Arithmetik-Register einfuegen, d.h. Berechnungsergebnis ausgeben) Cave: Punkt verwenden fuer Gleitkommarechnung, sonst nur Integerrechnung Ctrl-r=20.5*3.7 :let i=5 Ctrl-r=i Variable i ausgeben * (Middle-Mouse-Clipboard) und + (Clipboard) :set noautoindent (empfohlen) Cave: "+p unterdrueckt im Unterschied zu "*p autoindent und andere Optionen "*yW Rest-Wort in Clipboard "*yaW Gesamt-Wort in Clipboard "*p Clipboard ausgeben - Syntax-Highlighting :syntax on :set syntax (zeigt an, welches Highlightin genutzt wird) :set syntax=html :set filetype=html Ctrl-L (Refresh Highlighting) Iterierte Werte erzeugen ======================== :let i=1 qa I Ctrl-R=i <Return> ) <Esc> :let i=i+1 <Return> q <Zeilen markieren> :'<,'>:normal @a 1) 2) ... 8) Inhalte von Variablen anzeigen ============================== 2 Varianten :echo &<var> :set var? Beispiele :set path? :echo &filetype :set filetype? :help runtimepath => Muster/Variablen des Suchpfades :echo &runtimepath => Ausgabe des aktuellen Pfades :echo &filetype => Dateityp der aktuellen Datei :echo &iskeyword :filetype => Ausgabe der Status zu filetype detection, plugin, indent betreffend die folgenden Einstellungen in .vimrc :set <option>! '!' am Ende => toggle current setting :set ignorecase! :set <option>& '&' am Ende => Default-Wert setzen Spezifische Anweisungen fuer eigenen Dateityp ============================================= .vimrc filetype on (Default) filetype plugin on filetype indent on .vim/filetype.vim autocmd BufNewFile,BufRead *.dict set filetype=dictionary Alternativ .vim/ftplugin/dictionary/hugo.vim oder .vim/ftplugin/dictionary.vim mit Inhalt z.B. set sw=8 Dictionary bekanntmachen und Wort-Trenner dafuer hinzufuegen (da sonst Umbruch an diesen Stellen) ================================================================================================= .vimrc set complete+=k Default: .,w,b,u,t,i <= nun auch mit "k" fuer Dictionaries (Ctrlx Ctrl-k) set dictionary+=~/.vim/heinz.dict set iskeyword+=-,/ <= Erweiterung der Wortzeichen, falls "/" und "-" in Dictionary vorkommen Cave: Danach werden "-" und "/" als Wortbestandteile und nicht mehr als Worttrenner gewertet
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 -P A0:G20/A30 Datei.sc >> Vorhandene_Datei.sc dito, jedoch Verschmelzung mit anderer sc-Datei 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 -v -P % Datei.sc > Auszug_Gesamtdatei_nur_mit_Werten.sc dito mit Pseudo-Range der Gesamtdatei sc -W A0:M126 Datei.sc > Bildschirm-Abbild.txt Erzeugt reine Textausgabe des angegebenen Ranges wie in sc-Sitzung auf dem Bildschirm dargestellt (also mit dortiger Formatierung) sc -W % Datei.sc > Gesamte_Datei_als_Bildschirmabbild.txt dito mit Pseudo-Range der Gesamtdatei Zweite Datei laden ================== M (Merge) => Eingabefeld oben links | sc -P %/A100 Hugo.sc piped/inkludiert den gesamten Inhalt aus Hugo.sc (Angabe % anstelle Ranges) ab Zelle A100 des aktuellen Dokumentes 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 Zeilenbreiten (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 W "Hugo.txt" AL0:AV18 Speichern des Bildschirmabbildes eines Range T => table-output gemaess Wert von tblstyle, z.B. CSV speichern mit ':'-Delimiter (cf. unten) Beispiel S set tblstyle=latex T "" E2:I7 speichert Range E2:I7 mit Defaultnamen und Endung .latex Cave: Erster " wird von sc gesetzt, zweiter ist zu ergaenzen, danach <TAB> fuer Range-Eingabe ~/.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 # ^t r <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 ^A => Gehe zu Zelle A0 ^L Display neu aufbauen/Schirm neu zeichnen z.B. nach ^X zur Anzeige von Formeln in Zellen mit Ueberlapp in Nachbarzellen w analog vim => naechster Wortanfang (== naechste gueltige Zelle) b analog vim => dito vorherige gueltige Zelle ^t Toggle Options a automatische Neuberechnung => explizite Neuberechnung mit '@' C (toggle Color) N (toggle Color fuer negative Zahlen => Farbpaar 2) E (toggle Color fuer fehlerhafte Zellen) r <Pfeiltaste> (toggle Bewegung nach Return) c Cell-Highlighting (Highlighting vs. <=) s colorslop => String, welcher laenger als aktuelle Zelle ist, auch dann in Nachbarzelle ueberlappen, wenn diese anderem Farbrange angehoert n quick numeric entry (Eingabe von Zahlen ohne "=") 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 :-/) Einstellung wird nicht in Datei gespeichert und ist daher nur temporaer, aber W <datei> uebernimmt die temporaeren locale-Formatierungen als Textdarstellung des aktuellen Bildschirmes color cslop (funktioniert scheinbar nicht als Eintrag in Konfigurationsdatei .scrc) Ueberlapp eines String in Nachbarzelle, welche anderem Farbrange angehoert Cave: Bei ^T S cslop wird in der Datei folgendes eingetragen set cslop tblstyle = latex 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. Kopieren Range => Range: c. <Target-Range-Angabe mit Cursor> <TAB> (Uebernahme markierten Target-Ranges) <TAB> <BACK> <Ueberschreiben> Angabe des Source-Range "x Naechstes yank/delete/pull-Command in Buffer x "ary <rangeauswahl mit Pfeiltasten> Range in Buffer a kopieren "app zuvor in Buffer a kopierten Range ausgeben Achtung: Zellreferenzen werden NICHT aktualisiert im Unterschied zu rc <dest> <src> 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) F A8:A8 "0.00 Eur" F A8:A8 ",0 Eur" (mit Tausendertrennzeichen) F A8:D8 "0 %" F A8:D8 "0.0000" F D7 "0 m3" Es kann hier auch ein Range eingegeben werden F B4:B8 "#,0.& \Liter" zu lesen als Zahl vor Tausendertrennzeichen mit mindestens einer 0 vor dem Dezimaltrenner '.' und danach so viele Zeichen wie Zellvorgabe fuer Dezimalstellen 0.01 ergibt (bei Zellvorgabe zweier Dezimalstellen) bei #,0.& => 0.01 #,.& => .01 .& => .01 # Zahl 0 Zahl mit 0-Padding . Dezimalpunkt % Prozentzahl durch Multiplikation mit 100 z.B. Eingabe = 0.025 rF <Bereichsauswahl> <Tab> "0.00 % (Formatierungsangabe mit %) => Anzeige: 2.5 % , 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 FCtrl-D%F => angezeigt als "^D%T" (z.B. fuer Inhalt =@dts(2021,12,31) => Ausgabe als 2021-12-31 Cave: Formatierter Datumswert erscheint so immer linksbuendig, also besser so eingeben FCtrl-D %F angezeigt als "^D %F" sinnvoll in .scrc entweder fkey 5 = "fmt $$ \"^D%F\"" oder mit der vorigen Anmerkung fkey 5 = "fmt $$ \"^D %F\"" Cave: CTRL-D muss in vim "verbatim" eingegeben werden via CTRL-V CTRL-D und erscheint dann in blauer Schrift als ^D Datumsfunktionen ================ Cave: Alle Datums-/Zeitfunktionen ausser @date liefern numerische Werte => Bei @date String-Eingabe (<>\) fuehrendes, automatisch gesetztes '"' loeschen wie immer bei String-Formeln, da sonst literal interpretiert @date(@dts(2022,01,01),"%F") => 2022-01-01 cf. man strftime fuer zulaessige %-Werte 2022.01.01 wird als Schnelleingabemoeglichkeit konvertiert zu @dts(2022,01,01) (aber nur, wenn als Zahlenwert eingegeben !) =2022.01.01 => @dts(2022,01,01) zusaetzliche Belegung des Label-Feldes moeglich mit >"2022.01.01 => kombiniert in Feld links oben: "2022.01.01" [@dts(2022,01,01)] (in Zelle dargestellt wird String, Epoc-Sekunden sind in numerischem Feld) Beispiele A0: =@dts(2022,1,1) => 1640991600 A1: =@dts(2022,1,31) => 1643583600 A2: =A1-A0 => 2592000 A3: >@date(@dts(2022,1,1),"%F") => 2022-01-01 A4: >@date(@dts(2022,1,1)+A2,"%F") => 2022-01-31 A5: =A2/(60*60*24) => 30 (Abstand in Tagen zwischen 01.01. und 31.12.2022) B1: >@date(A1,"%F") => 2022-01-31 (Formatierungsfunktion) B1: F CTRL-D%F (implizite Formatierung als Datum 2022-01-31) Cave: Moeglich ist Schnelleingabe A0: =2022.01.01 => [@dts(2022,01,01)] mit Anzeige des numerischen Feldes in Epoc-Sekunden, z.B. 123456 A0: >@date(A0,"%F") => >{@date(A0,"%F")} [123456] Formel aus numerischem Feld wird durch Epoc-Sekunden ersetzt, angezeigt wird der String 2022-01-01 aber: anschliessende Aenderung des numerischen Feldes durch z.B. =2022.01.31 => >2022-01-01 [@dts[2022,01,31)] macht wiederum den String konstant (mit dem vorigen Wert), d.h. man kann nur in entweder dem numerischen oder Label-Feld eine Formel unterbringen. Diese wird sofort in Wert umgewandelt, sobald das jeweils andere Feld eine Formel erhaelt. # 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>) <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: F "#,0.& \Eur" <RETURN> Tipp: Format kann nach Ctrl-C mit Shift-Ins eingefuegt werden Beispiel: f= (Auswahlmenue 0-9 erscheint) 5 "#,0.& ;(#,0.&)" ^x Formeln aller Zellen anzeigen ^r Anzeige aller Zellen mit numerischen Werten OHNE Formeln 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, Spalte kopieren "append") 5ar 5 mal die aktuelle Zeile kopieren dr,dc Beispiel: 5dr or,oc dd Aktuelle Zeile loeschen x Aktuelle Zelle loeschen yr,yc,yy (yank row, colum, cell - 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 row, colum, cell pC (wie pp, aber Aenderung der Zell-Referenzen) p. (wie pC, aber mit Cursor-Auswahl des Ziel-Ranges) => beliebig viele Kopien genau EINER Quell-Zelle in Ziel-Range Cave: Funktioniert nicht mit mehr als einer Quell-Zelle Beispiel yy <Return> p. <Range mit Cursor markieren> <Return> => n Kopien der kopierten Zelle 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> range fill => 10 Zellen ab 10, inkrementiert um 1 Beispiel: rf 10l <TAB> Hugo 0 <RETURN> increment '0' bewirkt Fuellung mit identischem Wert fuer alle Zellen Cave: Fuellt numerisches Feld, nicht Textfeld ! rx Range loeschen => p-Kommandos ry Range yank (Referenzen fix) => p-Kommandos Range-Angabe ist der zu kopierende Range ry 5l ry <Cursor-Auswahl> ry <TAB> <BACKSPACE> <ueberschreiben> 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 aktuelle Zelle wird als destination range vorbelegt, destination range kann mit - Cursorbewegung <RETURN> vergroessert werden Source-Range-Angabe danach mit - <TAB> <BACKSPACE> [ueberschreiben], z.B. <TAB><BACK> C4:H4 <RETURN> rm fast wie rc, aber 'move' Vorgehen 1 Links oben in Zielrange positionieren rm <Tab> <Tab> Ergaenzung des zweiten <TAB> mit Quellrange ueberschreiben (C17:C26) <RETURN> Vorgehen 2 (optimal) Links oben in Zielrange positionieren rm (Target-Range (einzelnes Feld) wird eingetragen mit Cursor in erste Zelle des Quell-Range wechseln <TAB> mit Pfeiltasten Quell-Range markieren <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 oder l,t,r,b rr a(all) <TAB> A0:Z100 A1:Z100 friert die oberste Zeile ein und erzeugt den Dateieintrag frame A0:Z100 A1:Z100 rr l A0:Z100 1 friert die aeusserst linke Spalte ein Cave: "freeze" funktioniert nur, sofern bei Scroll der innere Range NICHT verlassen wird => immer Range definieren, welcher mehr Zellen umfasst als auf Bildschirm dargestellt einen outer-range A0:Z1000 kann man sich auch besser merken fuer unframe-command rv Formeln in Zahlen wandeln rd Range definieren (Bezeichner kann danach anstelle des Ranges verwendet werden) Cave: Zuvor mit ^T l Autolabelling disablen andernfalls wird Range-Name in (leere) Zelle links daneben geschrieben und in Datei als z.B. label C4 = "hugo" gespeichert rd "Wartung" AB10:AF73 rd "Wartung"<TAB> <Range-Auswahl mit Cursor-Tasten> g "Wartung" => AB10 rc F17 Wartung Ranges werden in Datei gespeichert als define ... ru Rangedefinition loeschen rs Sortieren mit Angabe von 3 Parametern Cave: Sortiert werden kann nur die Zeilenabfolge Vorgehen Links oben im Range positionieren rs (ggf. mit Pfeiltasten markieren und) <Tab> Rangeangabe vervollstaendigen (eintippen, springen oder mit Pfeiltasten markieren) optional: Sortieranweisungen in "..." eingeschlossen (auch mehrere Spalten nacheinander) 1.) + oder - 2.) # oder $ (# fuer numerisch, $ fuer String) 3.) <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> rd Range definieren rd "Name" <TAB> Cursor bewegen oder Range eingeben (Backspace + Ueberschreiben) g <Name> springt zu definiertem Range rS Range-(und andere) Definitionen anzeigen ru Range entdefinieren ru "Name" 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 Cave: Ist das Feld numerisch, wird ein * als Kommentarkennzeichen in Farbe 4 vorangestellt ** springt zu Zelle mit Kommentartext '' Ruecksprung zu Ausgangszelle *d Kommentarverweis loeschen *s zeigt Zellen mit Kommentarverweis durch Kontrastfarbe Funktionen/Formeln ================== Fuer alle elementar und wichtig: ~e ist Verneinung eines Ausdruckes e 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(...) >@sval("D",0) => Uebernahme des Labels aus D0 und nicht >"@sval("D",0) @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 @sum(A0:A3,~@eqs(B0,"ja")) <= bedingte Summation mit Verneinung ('~' ist boolsches Nein) 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 A7: 10.5 Eingabe: >@fmt("zu viel %10.2f",A7) => "zu viel 10.5" Cave: Eingabe mit ">", da String-Funktion @sum(A0:A9,A0>5) @sum(A0:A9,A0=5) numeric equality <=> @eqs(A0,"ok") string equality summiert alle Zellen von A0 bis A9, welche jeweils (!) groesser/gleich 5 sind Externe Funktionen ================== @ext(se,e) se=string expression e=(numerical) expression 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 Ergebnis editieren 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) Cave: Vor Einfuegen in Eingabefeld links oben automatisch eingefuegtes '"' loeschen ! 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 (genau und nur) 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 Eingabe 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 Formeln resultieren CTRL-R ist das genaue Gegenteil => Anzeige aller Zellen mit numerischen Werten OHNE Formeln => Anzeige aller in einem Formular AUSZUFUELLENDEN Zellen :-) g <suchbegriff oder zelle> Cave: Alle in "" eingeschlossenen Suchbegriffe sind regular expressions Gesetzt werden muss wie immer nur der ersten '"' Cave: Pattern muessen nur Teil-String matchen Cave: Mustersuchen bei Zahlen mit g #" beziehen sich immer auf das dargestellte Ergebnis, d.h. auch Formelergebnisse werden damit gefunden Cave: Mustersuchen mit g %" beziehen sich immer auf die Formeldarstellung Cave: Regulaere Ausdruecke immer analog ed (Vorlaufer vi(m)s) ======================================================================== g a14 => Zelle mit Koordinaten g 10.7 => Zelle mit dieser Zahl Cave: gesucht wird nach diesem Zahlwert, nicht einer formatierten Zahl-Darstellung g "Abschlaege => Zelle mit diesem regulaeren Ausdruck g #"6,362 kg => Suche nach formatierter Zahl (verstanden als regulaerer Ausdruck der formatierten Zahldarstellung) g #".*15.* => findet >2,150.43< ebenso wie >115.61 Eur/mon< Cave: g #"42" => findet alle direkt eingegebenen oder errechneten Zahlen, welche "42" ENTHALTEN ! Cave: g #"2150 => findet mit Tausendertrenner dargestellte Zahl "2,150" NICHT => es wird immer nach der FORMATIERTEN Darstellung gesucht g #".72 => sucht nicht nach <Komma>72, sondern beliebige Ziffer, gefolgt von 72 g #"8.*% => findet z.B. '82 %','62.81 %", g %"T32 => Suche nach Zelle mit Formel, welche T32 beinhaltet (==referenziert) g %".*B.*" => Suche nach Zellformeln, welche ein 'B' beinhalten =B6 =12*B7 g "^.*Vita.*$ => Suche mit regulaerem Ausdruck n => Wiederholung der Suche/nachesten Treffer anzeigen g<return> => Widerholung der letzten Suche (analog n) ! <Return> => Shell beginnen .. Abschluss mit exit und "press any key to continue ..." ! ls => Shell Befehl ausfuehren psc (prepare (data for) sc) =========================== Cave: Integer werden als Zahlen erkannt; Gleitkommazahlen nur, wenn Dezimaltrenner ein '.' ist (und andernfalls als String interpretiert). dos2unix Master.csv psc -C2 -k -d\; < Master.csv > Master.sc -C2 : Spaltenbreite 2 Stellen weiter als fuer breitesten Eintrag noetig -k : keep all delimiters => leere Zellen nicht verwerfen -d\;: Delimiter ; Alternative (mit automatischer Wandlung deutscher Gleitkommazahlen): mycsv2sc Export zu csv ============= Export als csv-Tabelle mit (innerhalb sc-Sitzung) S tblstyle=0 als Default bereits eingestellt und als solches nicht in *.sc sichtbar (jedoch aus .scrc uebernommen) T Export als Tabelle mit ':' als Trennzeichen dos2unix Export.csv vim Export.csv %s/:/;/g
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)
Unterscheidung Windows Panes (Unterteilungen ein und desselben Fensters) Befehle/Optionen oft mit Folge-Option -t (== target) Clients tmux list-clients Sessions tmux ls Liste Sessions tmux list-sessions Liste Sessions tmux new-session -s "default" tmux kill-session -t myname Ctrl-b d detach tmux a attach tmux new -s myname Neue Session "myname" tmux a -t myname (re)attach session "myname" Ctrl-b s Liste Sessions 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 window Ctrl-b , name window 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 Folgeeingabe der Nummer waehrend Anzeige wechselt zu diesem Panel 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 Ctrl-b Alt 1 Nebeneinander mit GLEICHER Breite Ctrl-b Alt 2 Untereinander mit GLEICHER Hoehe 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) Command-Mode Ctrl-b : Enter command-mode : split-window -h untereinander : split-window -v nebeneinander : resize-pane -L|R|D|U 20 20 Zellen in angegeben Richtung vergroessern/verkleinern 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}' set -g display-panes-time 4000 Millisekunden, ueber welche die Pane-Nummern mit Ctrl-b q angezeigt werden und einen Wechsel durch Folgeeingabe der Nummer erlauben
sed -i.bak -e '5,10d;12d' file # Zeile 5 bis 10 und Zeile 12 loeschen; Backup-File anlegen -------------------------------------------------------------------------------------------------------------------- Option -E ermoeglicht extended regular expressions, d.h. keine Escape-\ vor z.B. Klammern sed -E ' s/([0-9])\.([0-9])/\1\2/g # Tausendertrenner entfernen ' Eingabe.csv > Ausgabe.csv -------------------------------------------------------------------------------------------------------------------- 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" -------------------------------------------------------------------------------------------------------------------- #------------------------------------------------------------------------------------------- # Nur Zeilen mit Datum oder "dispatched" beibehalten #------------------------------------------------------------------------------------------- sed -n '{ /\(^ *[0-9]\{4\}\|dispatched\)/{ # Nur Zeilen mit Datum zu Beginn oder "dispatched" beibehalten s/^ *// # Initialen Whitespace loeschen s/\([0-9]\{4\}\)[- ]\([0-9]\{2\}\)[- ][0-9]\{2\}/\1\2/ # 2023-01-04 oder 2023 01 04 => 202301 von Datum nur Jahr und Monat beibehalten (auch bei fehlerhaften Eintragen ohne Bindestrich) s/\./,/g # Dezimaltrenner bereinigen (Cave: lazy-Variante: nicht geprueft wird, ob Punkt zwischen 2 Zahlen steht) s/ \+PRO/ PRO/ # Einzelnes Blank vor Projektnummer verdoppeln (fuer spaetere Strichpunktersetzung) /\(pending\|disabled\)/Id # Status-Ausschluesse s/groeger/Groeger/I s/troeger/Troeger/I s/ARNO/Arno/ s/ \{2,\}/;/g # Blankfolgen >= 2 durch ; ersetzen (funktioniert wegen "greedy") p # Ausgabe } }' "$out1" > "$out2" sed -i -n ' $!{ # Fuer alle Zeilen bis auf die letzte h # Zwischenspeichern n # Folgezeile einlesen /dispatched/{ # "dispatched"-Zeile ? g # Holdspace => Patternspace s/$/;dispatched/ # "dispatched" mit ";" anhaengen p # Ausgabe } /dispatched/!{ # Nein, Datumszeile x # Patternspace <=> Holdspace s/$/;/ # ";" anfuegen p # Ausgabe g # Patternspace => Holdspace s/$/;/ # ";" anfuegen p } } ${ s/$/;/ # ";" anfuegen und p # ausgeben } ' "$out2"
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 if((col+0) > NF) # Cave: Zwangskonvertierung String => Zahl 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") #--------------------------------------------------- monthString="Jan Feb Maer Apr Mai Jun Jul Aug Sep Okt Nov Dez"; split(monthString,months); printf(Monat: %s\n",months[5]); #--------------------------------------------------- match("foobar",/(f+).*(b+)/,matchArr) printf("Alles: %s\n",matchArr[0]); printf("Erste Klammer: %s\n",matchArr[1]); printf("Zweite Klammer: %s\n",matchArr[1]); #--------------------------------------------------- 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); # Cave: "g" == global .... 1 waere 1.Treffer ... 3 waere 3. Treffer Synonym sind ============ phone=gensub(/([0-9]) +([0-9])/,"\\1\\2","g",phone); # Leerzeichen zwischen Zahlen ersetzen gsub(/ +/,"",phone); # Cave: gensub liefert ersetzten string, gsub die Anzahl Ersetzungen zurueck und aendert string direkt 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 #--------------------------------------------------- # date and time #--------------------------------------------------- now=systime(); # number of seconds (epoch) then=mktime("2023 12 31 23 00 00") printf("%s <=> %s\n",strftime("%F",now),strftime("%F",then)); # %F analogous to 'date'-Format-String => "%Y-%m-%d" year=2022; month=06; day1=13; day2=27; secsPerDay=3600.0*24.0; startString=year " " month " " day1 " 03 00 00"; startTime=mktime(startString); endString=year " " month " " day2 " 03 00 00"; endTime=mktime(endString); days=sprintf("%d",((endTime-startTime)/secsPerDay)+1);
.config/mc/mc.ext (Shift) F5 # Copy (Shift) F6 # Move F7 # Verzeichnis anlegen F8 # Delete F10 # Beenden F4 # vim F3 # Viewer Ctrl-i/TAB # Panel wechseln Alt-, # Toggle Left/Right - Top/Bottom-Ansicht Alt-t # Cycle Listing-Modes Ctrl-t/Insert # Objekte selektieren/deselektieren Ctrl-u # Panels tauschen Ctrl-PgUp # Vaterverzeichnis # oder in /etc/mc/mc.default.keymap festlegen (Raspberry) 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-g # Oberste, mittlere, unterste _sichtbare_ Datei auswaehlen -r -j Alt-v/Ctrl-v PgUp/PgDown # Eine Seite nach unten/oben Alt-</> HOME/END # zu erster/letzter Datei springen Alt-s <Anfangsbuchstaben> # Springe zu Datei nach Muster ... (Wildcards * ?) mehrfach => naechster Treffer Ctrl-\ # Directory Hotlist (funktioniert nicht unter Windows (cygwin/wsl) Ctrl-o # Toggle shell Ctrl-space # Verzeichnisgroesse ermitteln (Anzeige im Panel) Ctrl-x (s|v|l) # Symbolische Links oder harten Link im anderen Verzeichnis anlegen -s: absoluter Pfad -v: relativer Pfad Ctrl-x c # chmod-Dialog Ctrl-x d # Verzeichnisse vergleichen Ctrl-x i # Toggle info der aktuellen Datei in anderem Panel Ctrl-x o # chown-Dialog Ctrl-x t # Markierte Datei => Kommandozeile Ctrl-x q # Toggle Quick-View der aktuellen Datei in anderem Panel (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 F2 # Popup-Auswahl der Aktionen fuer markierte Dateien F2-@ # Kommando auf selektierter Datei ausfuehren SSH/SFTP F9 R SFTP Achtung: .ssh/config wird ignoriert Shell-Link .ssh/config funktioniert cd sftp://heinz@strato cd sh://heinz@strato Ruecksprung: cd Command-Line z.B. cd ... ESC-Tab => autocompletion mehrfach => Auswahl F9 => Options => Configuration ESC-Tastenmodus => Einzelner Tastendruck
cf. Abschnitte INCLUDE/EXCLUDE PATTERN RULES ANCHORING INCLUDE/EXCLUDE PATTERNS in man-Page Wenn Dateien nur aufgrund abweichender Groesse uebertragen werden sollen: rsync -rzv(n) --size-only dir/* dir2/ Grundregeln =========== Pfade sind alle rekursiv ab root qualifizierten Verzeichnisse Pattern werden rekursiv ueber alle so qualifizierten Pfade ab root matched /source /source/afile /source/adir /source/adir/bdir /source/adir/bdir/cfile Jeder Match wird von links nach rechts auf den gesamten aktuellen Pfad angewandt include-Matches kompensieren exclude-Matches nur genau auf derselben Ebene == Verhalten von unison da auf jeder Ebene ueber Aus-/Einschluesse enschieden wird, kommen unterhalb eines Ausschluesses gelegene Einschluesse nicht mehr zum Zuge excludeFile */ => Ausschluss aller Verzeichnisse includeFile /subdir/hugo.java => wird nicht mehr angewandt, da subdir bereits ausgeschlossen wurde -a impliziert recursive traversal Trailing '/' oder nicht hat nur bei Quellverzeichnis Bedeutung rsync -a /source /target[/] Uebertraegt source rsync -a /source/ /target[/] Uebertraegt Inhalte von source Root ist immer das vor dem letzten '/' beschnittene Quellverzeichnis rsync -a /a/b/c/d/ .......... Root: /a/b/c/d rsync -a /a/b/c/d .......... Root: /a/b/c * matched alles, stoppt jedoch bei '/', d.h. '/' wird mit-matched, DANACH jedoch gestoppt => excludeFile: * => schliesst alles aus, d.h. alle Verzeichnisse (mit trailing '/') und alle Dateien includeFile: */ => schliesst alle Verzeichnisse ein ? matched genau ein Zeichen außer '/' ** matched alles inkl. '/' dirname/*** matched wie zusammen dirname dirname/** Muster mit fuehrendem '/' sind unterhalb Root verankert Muster ohne fuehrenden '/' matchen ueberall Muster mit '/' irgendwo (ausser am Ende) matchen den gesamten Pfad sub/foo => matched ueberall im Pfad Muster mit trailing '/' matchen nur Verzeichnisse (am Ende des Pfades) */ => matched jeweiliges Endverzeichnis des Pfades und damit rekursiv jeden denkbaren Pfad ab root rsync --exclude='*/' -a . version_3 alle Dateien (jedoch kein Verzeichnis) in Unterverzeichnis version_3 archivieren rsync -a /source/adir /target excludeFile /adir => matched nur /source/adir, nicht /source/bdir/cdir/adir bdir/cdir => matched /source/adir/bdir/cdir Strato_alt => Strato_neu: ========================= .ssh/config Host strato_neu Hostname 87.106.235.227 IdentityFile ~/.ssh/strato/id_rsa_%r LocalForward 4444 127.0.01:873 ssh root@strato_neu rsync --archive --password-file=/etc/rsyncd.secrets /var/www/html/ rsync://root@localhost:4444/Web Beispiel anhand des Klonens von Partitionen =========================================== rsync --stats --progress --numeric-ids -axAhHSP /mnt/* /media/austausch Cave: der '*' ist optional Optionen a: archive-mode == -rlptgoD r: recursive l: links als links kopieren p: preserve permissions t: preserve modification times g: preserve group o: preserve owner D: == --devices (preserve device file (super-user only)) --specials (preserve special files) x: only-one-filesystem (== exclude mounts darunter) A: (preserve acls) kann entfallen H: preserve hard-links h: human-readable S: intelligentes Kopieren von sparse-files P: partial progress
Generell ======== Grundregel 1: Man muss aufpassen, sich mit ignore nicht ein Verzeichnis bereits auszuschliessen, auf dessen spezielle Elemente (Verzeichnisse oder Dateien gleichermassen) danach eine ignorenot-Regel angewandt werden soll => nicht moeglich ist daher, in einem Verzeichnisbaum nur alle *.java-Dateien oder alle src-Verzeichnisse zu sichern Grundregel 2: Jedes Element wird auf ALLE Regeln zu matchen versucht, sofern ein vorheriges ignore dieses nicht ausgeschlossen hat => Eine Anweisungsfolge Path=.ssr ignore=Name logs anstelle ignore=Path .ssr/logs ist gefaehrlich, da die ignore-Anweisung auch auf ALLE anderen Pfad-Anweisungen angewandt wird Wenn ein qualifiertes Element mit ignore ausgeschlossen wurde, kann ignorenot nicht auf Unterelemente angewandt werden, d.h. ignorenot Path=.ssr verwirft .ssr und es gibt gar keine Elemente .ssr/* mehr, auf welche ein folgendes ignorenot-Muster ignorenot Path=.ssr/*.content angewandt werden koennte Richtig folglich ignore=Path .ssr/* ignorenot=Path .ssr/hugo .ssr wird nicht ausgeschlossen => naechste Elemente fuer den Algorithmus sind nun alle .ssr/* => .ssr/* werden ausgeschlossen, .ssr/hugo jedoch nicht Daher funktioniert auch Ignore=Regex .*\.class matched den gesamten Pfad bis zu einem Verzeichnis oder einer Datei mit Endunge .class und schliesst daher effektiv alle *.class-Dateien in allen Unterverzeichnissen aus wohingegen das vermeintliche Positiv-Beispiel Ignorenot=Regex .*\.java nur auf Verzeichnisse und Dateien ueberhaupt angewandt wird, welche nicht zuvor durch ein Ignore=Path ... ausgeschlossen wurden es funktioniert also nicht Ignore=Path repository/* => schliesst alles direkt unter repository (bereits) aus, z.B. repository/subdir IgnoreNot=Regex .*\.java => wuerde nur fuer repository/*.java (aus der ignorierten Teilmenge) funktionieren, da alle respository/<unterverzeichnis> bereits ignoriert sind, wodurch z.B. repository/subdir/hugo.java als Match auf .*/.java gar nicht mehr ausgewertet wird Synonym sind IgnoreNot=Name *.ext Ignoriert jedes Unterverzeichnis oder jede Datei, welche auf .ext enden (Achtung globbing: '/' wird durch * nicht matched, . matched '.') Ignorenot=Regex .*/\.ext Matched gesamten Pfad bis zu einem Verzeichnis/einer Datei mit Endung .ext Es klappt zumindest angenaehert, d.h. bestmoeglich path=A #------------------------------------------------------------------------------------------------------------------------------------ # Globbing: Datei oder effektiv letztes Verzeichnis beginnend mit oder ohne '.', beliebiger Zeichenfolge, '.' und beliebiger Endung ausschliessen # # Cave: Annahme ist, dass es kein Verzeichnis, sondern nur Dateien mit einem '.' gibt # Dateien ohne '.' werden leider ebenfalls gesichert, da der Ausschluss nur von Dateien (nicht Verzeichnissen) ohne '.' nicht moeglich ist #------------------------------------------------------------------------------------------------------------------------------------ ignore=Name {,.}*.* #------------------------------------------------------------------------------------------------------------------------------------ # Globbing: Dito, jedoch mit Endung java #------------------------------------------------------------------------------------------------------------------------------------ ignorenot=Name {,.}*.java Achtung ======= Path, Name und PathBelow verwenden globbing * matched beliebige Zeichenfolge außer '/' und zu Beginn ein '.' ? matched genau ein Zeichen außer '/' und zu Begin ein '.' ausserdem: [abc] Zeichen a oder b oder c und {xx,yy,zz} Zeichenfolge xx oder yy oder zz Regex verwendert Posix-Extended-Regular-Expression, d.h. .* matched alle Zeichen INKL. '/' und . matched ein beliebiges Zeichen Anweisungen =========== ignore (oder ignorenot) Cave: ignore=Regex ... Posix-Extended-Regular-Expression muss den gesamten Pfad matchen \. matched '.' .* matched alles, also auch '/' Beispiel ignore=Regex .*\.class sichert alles in allen Unterverzeichnissen außer Verzeichnissen oder Dateien, welche auf .class enden, da .* auch '/' matched ignore=(Path|PathBelow) ... File-Globbing * und ? Cave: * matched NICHT '/' BelowPath matched auf Path, zusaetzlich jedoch auch auf alles Darunterliegende ignore=Name logs jeder Unterverzeichnisbaum, dessen letztes Verzeichnis logs ist, oder jede Datei namens logs irgendwo im Baum wird ignoriert Fuer den Ausschluss einer Dateiart ausser in einem bestimmten Unterverzeichnis ignore=Name *.ext Cave: Globbing ignorenot=Regex .*/sollverzeichnis/*\.ext Cave: Posix-Extended-Regular-Expression
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 ===== ############################################################################################# # Sensitivity-Label lesen ############################################################################################# def getSensitivityLabel(file) #-------------------------------------------------------------------------------------------------- # List das SensitivityLabel einer Excel-Datei, welche bereits (manuell) klassifiziert worden war #-------------------------------------------------------------------------------------------------- begin (! File.exists?(file)) && die("getSensitivityLabel: Datei #{file} existiert nicht") #---------------------------------------------------------------------------------------------- unless($excel) startExcel end #-------------------------------------------------------------------------------------------- # konvertieren ... #-------------------------------------------------------------------------------------------- book=$excel.Workbooks.Open(file); checkValue(book) labelInfo=book.SensitivityLabel.getlabel(); puts("LabelName: #{labelInfo.LabelName}"); puts("LabelId: #{labelInfo.LabelId}"); puts("SiteId: #{labelInfo.SiteId}"); puts("Assignment-Method: #{labelInfo.AssignmentMethod}"); rescue => exception die("convertExcelCSVByNumber: #{exception.message}") ensure Dir.chdir($cwd) end end ############################################################################################# # Sensitivity-Label setzen ############################################################################################# def setSensitivityLabel(file) #-------------------------------------------------------------------------------------------------- # Setzt das SensitivityLabel einer Excel-Datei #-------------------------------------------------------------------------------------------------- begin (! File.exists?(file)) && die("getSensitivityLabel: Datei #{file} existiert nicht") #---------------------------------------------------------------------------------------------- unless($excel) startExcel end #-------------------------------------------------------------------------------------------- # konvertieren ... #-------------------------------------------------------------------------------------------- book=$excel.Workbooks.Open(file); checkValue(book) labelInfo=book.SensitivityLabel.createLabelInfo() labelInfo.AssignmentMethod=1 # MsoAssignmentMethod.PRIVILEGED labelInfo.LabelId=LABELID labelInfo.SiteId=SITEID labelInfo.LabelName="Dr. Heinz Breinlinger" book.SensitivityLabel.setLabel(labelInfo,labelInfo) book.saveAs(file,ExcelConst::XlWorkbookDefault) getSensitivityLabel(file); rescue => exception die("convertExcelCSVByNumber: #{exception.message}") ensure Dir.chdir($cwd) end end #-------------------------------------------------------------------------------------------- # ';' in Text ersetzen, da csv-Trennzeichen #-------------------------------------------------------------------------------------------- puts("Replacing ; in sheet #{sheetName} ...") sheet.range("A1:ZZ1000").Replace({ "What" => ";", "Replacement" => "," }) #-------------------------------------------------------------------------------------------- # Zeilenumbrueche ersetzen #-------------------------------------------------------------------------------------------- puts("Replacing ; in sheet #{sheetName} ...") sheet.range("A1:ZZ1000").Replace({ "What" => "\n", "Replacement" => " " }) book.saveAs(file,ExcelConst::XlWorkbookDefault) #--------------------------------------------------------------- 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") #----------------------------------------------------------------------------- # Checkboxen loeschen #----------------------------------------------------------------------------- doc.FormFields.each{ |field| if(field.Type == WordConst::WdFieldFormCheckBox) puts("Erasing checkbox #{i+=1} ...") field.CheckBox.value=false end } #----------------------------------------------------------------------------- # Checkboxen setzen #----------------------------------------------------------------------------- checkBoxes=$contractHash["checkboxes"]; checkBoxes.split(',').each{ |name| puts("Setting checkbox #{name} ...") doc.FormFields(name).CheckBox.value=true; # Word wirft Fehler, wenn kein Form-Element dieses Namens vorhanden => keine Pruefung noetig } #----------------------------------------------------------------------------- # Textersetzungen #----------------------------------------------------------------------------- wordReplace(doc,"<Hugo>","Willi") #----------------------------------------------------------------------------- # Textformularfeld loeschen/setzen #----------------------------------------------------------------------------- # doc.FormFields("datum").TextInput.Clear # doc.FormFields("datum").Result="01.01.2024" #----------------------------------------------------------------------------- # Kalkulationstabelle einsetzen #----------------------------------------------------------------------------- # doc.ActiveWindow.Selection.InsertFile("C:\\Work_Config\\Budget\\Vertraege\\adesso\\Vertrag\\service-description.docx") #----------------------------------------------------------------------------- # Bild an Cursor-Position (Selection) einfuegen #----------------------------------------------------------------------------- # doc.ActiveWindow.Selection.InlineShapes.AddPicture("C:\\Work_Config\\Budget\\Vertraege\\adesso\\Vertrag\\calculation.png",false,true) #----------------------------------------------------------------------------- # Bild nach n. Buchstaben/Paragraphen einfuegen #----------------------------------------------------------------------------- # doc.Range(200).InlineShapes.AddPicture("C:\\Work_Config\\Budget\\Vertraege\\adesso\\Vertrag\\calculation.png",false,true) # doc.Paragraphs(5).Range.InlineShapes.AddPicture("C:\\Work_Config\\Budget\\Vertraege\\adesso\\Vertrag\\calculation.png",false,true) #----------------------------------------------------------------------------- # Bild in (einzig) vorhandenes Inhaltssteuerelement (aus Entwicklertools) # des Typs Bild einfuegen, d.h. das vorhandene Bild aendern #----------------------------------------------------------------------------- doc.ContentControls.each{ |contentControl| if(contentControl.Type == WordConst::WdContentControlPicture) puts("Found Picture-Control"); contentControl.Range.InlineShapes.AddPicture("C:\\Work_Config\\Budget\\Vertraege\\adesso\\Vertrag\\calculation.png",false,true) end } #----------------------------------------------------------------------------- # Anzahl der Zeichen einer Auswahl ausgeben (=> Ermittlung des Zeichenindex ab Anfang moeglich) #----------------------------------------------------------------------------- # puts("Zeichenzahl: #{doc.ActiveWindow.Selection.Characters.Count}") #----------------------------------------------------------------------------- # Bookmark loeschen #----------------------------------------------------------------------------- doc.Bookmarks.each{ |bookmark| if(bookmark.Name == "definitions") puts("Bookmark-Start: #{bookmark.Start}"); puts("Bookmark-End: #{bookmark.End}"); bookmark.Select doc.ActiveWindow.Selection.Delete end }
top === R: Sortierreihenfolge umkehren P: Nach CPU sortieren M: nach Speicher sortieren <>: Sortierspalte wechseln j: Prozessnamen => rechts blank: Update der Liste (unabhaengig vom eingestellten Intervall) Toggle 1: Anzeige je CPU/Core l: Last (1. Zeile) 1 == Auslastung bei 1 CPUs (Anzahl wartender Prozesse) 4 == Auslastung bei 4 CPUs t: CPU/Task Prozentual mit/ohne Balken m: Memory (Prozent und xByte, je nach Option E) E: KByte => Petabyte B: Bold overall an/aus b: Bold Sortierspalte/relevante Zeile vs. Blocksatz Sortierspalte/Zeile x: Toggle sort field V: Forst-View v: mit Unterprozessen c: Prozesse mit Pfadangabe S: Zeitangabe L Text: Prozessnamen "Text" finden (Cave: Keine '"') &: naechsten Treffer finden L <Return> Modus verlassen f/F: Filterliste festlegen s: Eintrag => Sortierkriterium d/blank: Auswahl <Rechtspfeil> <auf/ab>: Nach oben oder unten verschieben <Enter> u "user": Nur Prozesse des Nutzers A: 4-Fensteransicht k: Signal an Prozess