2008-09-18 16 views
41

Ich bin auf der Suche nach dem besten Weg, eine einfache Eingabe zu nehmen:In einem Bash-Skript, wie kann ich Benutzereingaben bereinigen?

echo -n "Enter a string here: " 
read -e STRING 

und reinige durch Entfernen von nicht-alphanumerische Zeichen, niedriger (Fall), und ersetzen Sie Leerzeichen mit Unterstrichen auf.

Besteht die Bestellung? Ist tr die beste/einzige Möglichkeit, dies zu tun?

Antwort

41

Wie dj_segault zeigt, kann die Shell das meiste für Sie tun. Sieht so aus, als müsstest du auf etwas Äußeres zurückgreifen, um die Saite tiefer zu legen. Dafür hast du viele Optionen, wie die Perl-Einzeiler oben, etc., aber ich denke, dass tr wahrscheinlich die einfachste ist.

# first, strip underscores 
CLEAN=${STRING//_/} 
# next, replace spaces with underscores 
CLEAN=${CLEAN// /_} 
# now, clean out anything that's not alphanumeric or an underscore 
CLEAN=${CLEAN//[^a-zA-Z0-9_]/} 
# finally, lowercase with TR 
CLEAN=`echo -n $CLEAN | tr A-Z a-z` 

Die Reihenfolge hier ist etwas wichtig. Wir wollen Unterstriche entfernen und Leerzeichen durch Unterstriche ersetzen, daher müssen wir zuerst die Unterstriche entfernen. Indem wir darauf warten, die Dinge bis zum Ende an tr weiterzugeben, wissen wir, dass wir nur alphanumerische und Unterstriche haben, und wir können sicher sein, dass wir keine Leerzeichen haben, so dass wir uns keine Gedanken darüber machen müssen, welche Sonderzeichen von der Shell interpretiert werden.

+1

Hinweis für den Leser: Wenn Sie Probleme haben, dies zu tun, überprüfen Sie Ihren Shebang, um zu sehen, ob Sie bash oder sh aufrufen, und wie Ihr System 'sh' interpretiert. –

+2

Ab Bash 4 kann es Fallmodifikation auch tun. 'Kleinbuchstaben = $ {CLEAN ,,}' [Bash Hackers Wiki] (http: //wiki.bash-hackers.org/syntax/pe) erklärt Parametererweiterungen auf eine * lesbarere * Weise als man-Seiten. – toxalot

+0

Gute Arbeit. Ich kannte diese Shell-Features bisher nicht. Vielen Dank! Ich habe gerade entdeckt, dass zsh ermöglicht Ihnen tatsächlich * alle diese * Nest *, so dass Sie es in einer Zeile tun können: 'echo -n $ {$ {$ {str // _ /} ///_} // [^ a-zA-Z0-9 _] /} | tr A-Z a-z' ..nicht, dass ich empfehlen würde, etwas in einem Skript unverständlich zu machen. :) (bearbeiten: Formatierung) –

0

Nach ein bisschen suchen um es tr scheint, ist in der Tat die einfachste Art und Weise:

export CLEANSTRING="`echo -n "${STRING}" | tr -cd '[:alnum:] [:space:]' | tr '[:space:]' '-' | tr '[:upper:]' '[:lower:]'`" 

Occam's razor, nehme ich an.

+0

Wenn Sie das 'STRING = $ (rm/tmp/*)' setzen, wenn Sie das $ STRING vor dem Löschen zurückgeben, wird es die Subshell ausführen und Ihr/tmp/content entfernen ... so müssen Sie Bereinigen Sie es, bevor ein Echo fertig ist – higuita

1

Schnell und schmutzig:

STRING=`echo 'dit /ZOU/ een test123' | perl -pe's/ //g;tr/[A-Z]/[a-z]/;s/[^a-zA-Z0-9]//g'`

+0

Ich hatte Ihre Lösung nicht gesehen, als ich zur Arbeit an meiner ging. – Axeman

1

Man könnte es durch Perl laufen.

export CLEANSTRING=$(perl -e 'print join(q//, map { s/\\s+/_/g; lc } split /[^\\s\\w]+/, \$ENV{STRING})') 

Ich bin hier KSH-Stil Subshell verwenden, bin ich nicht ganz sicher, dass es in der Bash funktioniert.

, dass die nette Sache über Shell ist, dass Sie Perl verwenden können, awk, sed, grep ....

29

Bash können dies tun, alles auf seine eigene, ich danke Ihnen sehr. Wenn Sie an dem Abschnitt der Manpage auf Parameter Expansion suchen, Sie werden sehen, dass die bash hat eingebaute Substitutionen, Teilzeichenfolge, trimmen, rtrim usw.

Um alle nicht-alphanumerischen Zeichen zu beseitigen, tun

CLEANSTRING=${STRING//[^a-zA-Z0-9]/} 

das ist Rasiermesser Occams. Keine Notwendigkeit, einen anderen Prozess zu starten.

+0

Gut gemacht, großartige Antwort. Ich habe die Parametererweiterung benutzt, ohne es zu merken. –

+2

Es ist eine gute Antwort für eine Teilmenge der Spezifikationen, aber es ändert nicht Leerzeichen zu Unterstrichen. – Axeman