[QUIZ#1] OnlyFoo (Bash)

OnlyFoo

Erfahrenes Mitglied
Noch eine Möglichkeit!
Code:
#!/bin/bash

# Argumente prüfen
if [ $# -ne 1 ] ; then
    echo "usage: $0 query"
    exit 1
fi

# gibt den übergebenen String in kleinen Buchstaben zurück
function toLower() {
    echo "$1" | tr '[:upper:]' '[:lower:]'
}

# indexOf( String, Zeichen, Anfang )
# Findet das erste vorkommen von Zeichen in String ab Anfang
# Wenn Zeichen nicht vorkommt, wird strlen( String ) zurückgegeben
function indexOfChar() {
    local STRING="$1"
    local CHAR="$2"
    let START=$3
    
    local PART="$( echo "${STRING:$START}" | cut -d"$CHAR" -f1 )"
    let INDEX=${#PART}
    let INDEX=INDEX+START
    echo $INDEX
}

# Variablen initialisieren
INPUT_FILE=presidents.txt
QUERY="$( toLower "$1" )"

# Zeilenweise Datei durchgehen
cat "$INPUT_FILE" | while read LINE ; do
    LINE_LOWER="$( toLower "$LINE" )"
    MATCH=true
    RESULT=
    
    let LAST_INDEX=-1
    LENGTH=${#LINE_LOWER}
    for(( i=0; i < ${#QUERY}; i++ )) ; do
        # Gucken wo das Zeichen im Rest vorkommt. 
        INDEX=$( indexOfChar "$LINE_LOWER" "${QUERY:$i:1}" $((LAST_INDEX + 1)) )
        
        # Das Zeichen kommt im Rest nicht mehr vor
        if [ $LENGTH -eq $INDEX ] ; then
            MATCH=false
            break
        fi
        
        # Wenn das Zeichen noch vorkommt, rest Anhängen.
        # Auf korrekte Benutzung von <..> achten...
        if [ $LAST_INDEX -ne $(( INDEX - 1)) ] || [ $LAST_INDEX -eq -1 ] ; then
            RESULT+="${LINE:$((LAST_INDEX+1)):$((INDEX-LAST_INDEX-1))}<${LINE:$INDEX:1}>"
        else
            RESULT="${RESULT:0:$(( ${#RESULT}-1 ))}${QUERY:$i:1}>"
        fi
        
        let LAST_INDEX=INDEX
    done
    
    # Den Rest hinter dem letzten Match anhängen, falls nötig.
    if $MATCH ; then
        if [ $LAST_INDEX -ne $LENGTH ] ; then
            RESULT+="${LINE:$((LAST_INDEX+1)):$((LENGTH-LAST_INDEX-1))}"
        fi
    fi
    
    # Ausgeben, wenn nötig.
    $MATCH && echo $RESULT
done
 

Dennis Wronka

Soulcollector
Schicke Loesung.

Was mir persoenlich sehr gefaellt ist dass Du $() anstelle von `` genutzt hast.
Konsequenterweise haettest Du dann aber auch, meiner Meinung nach, Variablen mit ${} nutzen sollen, also z.B. ${LINE_LOWER} anstelle von $LINE_LOWER.
 

OnlyFoo

Erfahrenes Mitglied
danke! :)

Was mir persoenlich sehr gefaellt ist dass Du $() anstelle von `` genutzt hast.
Konsequenterweise haettest Du dann aber auch, meiner Meinung nach, Variablen mit ${} nutzen sollen, also z.B. ${LINE_LOWER} anstelle von $LINE_LOWER.
Ich finde $(...) einfach übersichtlicher als `...` (wegen '...', und der Klammerung/Schachtelung natürlich)... aber ich finde, dass das mit $ und ${...} nicht viel zu tun hat, weil Variablen Schachtel ich ja normalerweise nicht =)... Wenn es der übersicht dient, nehm ich aber auch gern mal ${dieseForm} ... :)
 

Dennis Wronka

Soulcollector
Es kann manchmal hilfreich sein wenn man Variablen aneinandergehaengt ausgeben will oder Text anhaengen will.

Mal ein Beispiel:
Bash:
MEINEVARIABLE="meinevariable"
echo "${MEINEVARIABLE}_meintext"
Dies gibt, wie erwartet "meinevariable_meintext" aus.

Ohne {} hingegen wird nichts ausgegeben, da versucht wird die, nicht gesetzte Variable ${MEINEVARIABLE_meintext} auszuwerten.

Und auch wenn
Bash:
echo $X$Y
durchaus funktioniert, so finde ich
Bash:
echo ${X}${Y}
doch etwas schoener.

Das aber nur mal so am Rande.

Edit: Ich frag mich nur warum der dumme Highlighter hier immer |> einfuegen muss wenn ich Variablen mit ${} schreibe...