Obwohl diese Antwort komplexer ist als die am besten bewertete, macht sie genau das: 'erstes Zeichen in Großbuchstaben in einer Variablen'. Die am besten bewertete Antwort hat diese Ergebnisse nicht. Sieht so aus, als würden einfache Antworten eher positiv bewertet als die richtigen?
Krzysztof Jabłoński
15
@ KrzysztofJabłoński: Tatsächlich führt die unten stehende "am besten bewertete Antwort" zu denselben Ergebnissen wie diese Antwort unter Bash 4. Diese Antwort hat den Aufwand, eine Subshell (eine andere Shell) aufzurufen, den Aufwand, das Dienstprogramm 'tr' (einen anderen Prozess) aufzurufen , nicht Bash), der Aufwand für die Verwendung eines Here-Docs / Strings (temporäre Dateierstellung) und zwei Substitutionen im Vergleich zur Antwort der am besten bewerteten Antwort. Wenn Sie unbedingt Legacy-Code schreiben müssen, sollten Sie eine Funktion anstelle einer Subshell verwenden.
Steve
2
Diese Antwort setzt voraus, dass die Eingabe nur in Kleinbuchstaben erfolgt. Diese Variante hat keine Annahmen: $ (tr '[: unter:]' '[: oben:]' <<< $ {foo: 0: 1}) $ (tr '[: oben:]' '[: unten: ] '<<< $ {foo: 1})
Itai Hanski
5
@ItaiHanski Das OP hat nicht angegeben, was mit den verbleibenden Zeichen geschehen soll, sondern nur mit dem ersten. Vermeintliche sie wollten sich ändern notQuiteCamelin NotQuiteCamel. Ihre Variante hat den Nebeneffekt oder zwingt den Rest in Kleinbuchstaben - auf Kosten der Verdoppelung der Anzahl von Unterschalen und Tr-Prozessen.
Jesse Chisholm
3
@ DanieleOrlando, stimmt, aber diese Frage hat keine anderen Tags als bash.
@CMCDragonkai: Um den ersten Buchstaben in Kleinbuchstaben zu schreiben, verwenden Sie "${foo,}". Verwenden Sie, um alle Buchstaben in Kleinbuchstaben zu schreiben "${foo,,}". Verwenden Sie, um alle Buchstaben in Großbuchstaben zu schreiben "${foo^^}".
Steve
1
Ich habe das versehentlich bemerkt ${foo~}und ${foo~~}habe den gleichen Effekt wie ${foo^}und ${foo^^}. Aber ich habe diese Alternative nie erwähnt.
Mivk
5
Dies scheint auf Macs nicht zu funktionieren. Erhalten des folgenden Fehlers:bad substitution
Toland Hon
1
@ TolandHon: Wie Sie wahrscheinlich bereits herausgefunden haben, müssen Sie auf Version 4.x aktualisieren oder eine andere Lösung ausprobieren, wenn dieser Computer aus irgendeinem Grund nicht aktualisiert werden kann.
funktioniert nicht unter MacOS10 Lion sed, seufz, das \ u erweitert sich zu u, anstatt ein Operator zu sein.
Vwvan
2
@vwvan brew install coreutils gnu-sedund befolgen Sie die Anweisungen, um die Befehle ohne Präfix zu verwenden g. Für das, was es wert ist, wollte ich die OSX-Version dieser Befehle seit dem Erhalt der GNU-Versionen nie mehr ausführen.
Dean
@vwvan: Ja, sorry, Sie werden GNU sedin diesem Fall brauchen
Steve
2
@ Dean: FWIW, ich wollte noch nie OSX ausführen :-)
Steve
5
Ändern Sie sed 's/./\U&/es einfach in und es wird auf POSIX sed funktionieren.
Endlich etwas, das mit einer Variablen und auf dem Mac funktioniert! Danke dir!
OZZIE
4
@ DanieleOrlando, nicht so tragbar, wie man hoffen könnte. tr [:lower:] [:upper:]ist eine bessere Wahl, wenn es in Sprachen / Gebietsschemas mit Buchstaben arbeiten muss, die nicht in den Bereichen a-zoder A-Zliegen.
Es kann auch in reinem Bash mit Bash-3.2 durchgeführt werden:
# First, get the first character.
fl=${foo:0:1}# Safety check: it must be a letter :).if[[ ${fl}==[a-z]]];then# Now, obtain its octal value using printf (builtin).
ord=$(printf '%o'"'${fl}")# Fun fact: [a-z] maps onto 0141..0172. [A-Z] is 0101..0132.# We can use decimal '- 40' to get the expected result!
ord=$(( ord -40))# Finally, map the new value back to a character.
fl=$(printf '%b''\'${ord})
fi
echo "${fl}${foo:1}"
Wie definiere ich foo? Ich habe es versucht, foo = $1aber ich bekomme nur-bash: foo: command not found
OZZIE
1
@OZZIE, keine Leerzeichen um die =in Zuordnungen. Dies wird Shellcheck.net programmgesteuert für Sie finden.
Charles Duffy
Ich vergesse das immer über Shell-Skripte ... nur Sprache, in der ein Leerzeichen (vorher / nachher) wichtig ist ... seufz (Python ist mindestens 4, wenn ich mich richtig erinnere)
OZZIE
@OZZIE, es muss wichtig sein, denn wenn es nicht wichtig wäre, könnten Sie es nicht =als Argument an ein Programm übergeben (woher soll es wissen, ob someprogram =es ausgeführt someprogramwird oder einer Variablen mit dem Namen zugewiesen wird someprogram?)
Was ist, wenn das erste Zeichen kein Buchstabe ist (sondern ein Tabulator, ein Leerzeichen und ein maskiertes Anführungszeichen)? Wir sollten es besser testen , bis wir einen Brief finden! So:
Bitte schreiben Sie saubereren Code! Ihnen fehlen überall Zitate . Sie verwenden veraltete Syntax (Backticks). Sie verwenden eine veraltete Syntax ( $[...]). Sie verwenden viele nutzlose Klammern. Sie gehen davon aus, dass die Zeichenfolge aus Zeichen aus dem lateinischen Alphabet besteht (wie wäre es mit akzentuierten Buchstaben oder Buchstaben in anderen Alphabeten?). Sie haben viel Arbeit, um dieses Snippet nutzbar zu machen! (und da Sie Regex verwenden, können Sie auch den Regex verwenden, um den ersten Buchstaben anstelle einer Schleife zu finden).
gniourf_gniourf
6
Ich denke du liegst falsch. Es ist der obligatorische Kommentar, der die Abwertung begleitet und alle falschen Muster und Missverständnisse der Antwort erklärt. Bitte lernen Sie aus Ihren Fehlern (und versuchen Sie vorher, sie zu verstehen), anstatt hartnäckig zu sein. Ein guter Gefährte zu sein, ist auch nicht mit der Verbreitung schlechter Praktiken vereinbar.
gniourf_gniourf
1
Oder wenn Sie Bash ≥4 verwenden, brauchen Sie nicht tr:if [[ $S =~ ^([^[:alpha:]]*)([[:alpha:]].*) ]]; then out=${BASH_REMATCH[1]}${BASH_REMATCH[2]^}; else out=$S; fi; printf '%s\n' "$out"
gniourf_gniourf
5
Dieser Code ist immer noch stark defekt. Es werden immer noch Backticks anstelle der modernen Substitutionssyntax verwendet. es hat immer noch unübertroffene Zitate; es fehlen immer noch Anführungszeichen an Stellen, an denen sie tatsächlich eine Rolle spielen ; usw. Versuchen Sie, einige von Leerzeichen umgebene Glob-Zeichen in Ihre Testdaten einzufügen , wenn Sie nicht glauben, dass diese fehlenden Anführungszeichen einen Unterschied machen, und beheben Sie die Probleme, die shellcheck.net findet, bis dieser Code sauber angezeigt wird .
Charles Duffy
2
Was die Sprache betrifft , die Sie aus unix.stackexchange.com/questions/68694/… zitiert haben , so vermissen Sie echo $fooein Beispiel für eine Situation, in der der Parser eine Liste von Wörtern erwartet . In Ihrem Fall sind echo ${F}die Inhalte von FString-Split und Glob-Expanded. Das gilt auch für das echo ${S:$N:1}Beispiel und den Rest. Siehe BashPitfalls # 14 .
Antworten:
quelle
notQuiteCamel
inNotQuiteCamel
. Ihre Variante hat den Nebeneffekt oder zwingt den Rest in Kleinbuchstaben - auf Kosten der Verdoppelung der Anzahl von Unterschalen und Tr-Prozessen.bash
.Ein Weg mit Bash (Version 4+):
Drucke:
quelle
"${foo,}"
. Verwenden Sie, um alle Buchstaben in Kleinbuchstaben zu schreiben"${foo,,}"
. Verwenden Sie, um alle Buchstaben in Großbuchstaben zu schreiben"${foo^^}"
.${foo~}
und${foo~~}
habe den gleichen Effekt wie${foo^}
und${foo^^}
. Aber ich habe diese Alternative nie erwähnt.bad substitution
Ein Weg mit
sed
:Drucke:
quelle
brew install coreutils gnu-sed
und befolgen Sie die Anweisungen, um die Befehle ohne Präfix zu verwendeng
. Für das, was es wert ist, wollte ich die OSX-Version dieser Befehle seit dem Erhalt der GNU-Versionen nie mehr ausführen.sed
in diesem Fall brauchensed 's/./\U&/
es einfach in und es wird auf POSIX sed funktionieren.quelle
Hier ist die "native" Art der Textwerkzeuge:
quelle
tr [:lower:] [:upper:]
ist eine bessere Wahl, wenn es in Sprachen / Gebietsschemas mit Buchstaben arbeiten muss, die nicht in den Bereichena-z
oderA-Z
liegen.Nur awk verwenden
quelle
Es kann auch in reinem Bash mit Bash-3.2 durchgeführt werden:
quelle
foo = $1
aber ich bekomme nur-bash: foo: command not found
=
in Zuordnungen. Dies wird Shellcheck.net programmgesteuert für Sie finden.=
als Argument an ein Programm übergeben (woher soll es wissen, obsomeprogram =
es ausgeführtsomeprogram
wird oder einer Variablen mit dem Namen zugewiesen wirdsomeprogram
?)Das funktioniert auch ...
Und so weiter.
Quellen:
Einführungen / Tutorials:
quelle
Um nur das erste Wort groß zu schreiben:
So schreiben Sie jedes Wort in der Variablen groß :
(funktioniert in Bash 4+)
quelle
foo='one two three'; foo=$(for i in $foo; do echo -n "${i^} "; done)
Kürzere Auflösung für jedes Wort. foo Jetzt ist "Eins Zwei Drei"Alternative und saubere Lösung für Linux und OSX, kann auch mit Bash-Variablen verwendet werden
gibt Abc zurück
quelle
Dieser hat für mich gearbeitet:
Suchen Sie nach allen * PHP-Dateien im aktuellen Verzeichnis und ersetzen Sie das erste Zeichen jedes Dateinamens durch Großbuchstaben:
zB: test.php => Test.php
quelle
Nur zum Spaß hier bist du:
quelle
Nicht genau das, was gefragt wurde, aber sehr hilfreich
Und das Gegenteil
quelle
erster Buchstabe zum unteren xc () {v-erster Buchstabe zum unteren | xclip -selection Zwischenablage}
quelle
Was ist, wenn das erste Zeichen kein Buchstabe ist (sondern ein Tabulator, ein Leerzeichen und ein maskiertes Anführungszeichen)? Wir sollten es besser testen , bis wir einen Brief finden! So:
quelle
$[...]
). Sie verwenden viele nutzlose Klammern. Sie gehen davon aus, dass die Zeichenfolge aus Zeichen aus dem lateinischen Alphabet besteht (wie wäre es mit akzentuierten Buchstaben oder Buchstaben in anderen Alphabeten?). Sie haben viel Arbeit, um dieses Snippet nutzbar zu machen! (und da Sie Regex verwenden, können Sie auch den Regex verwenden, um den ersten Buchstaben anstelle einer Schleife zu finden).tr
:if [[ $S =~ ^([^[:alpha:]]*)([[:alpha:]].*) ]]; then out=${BASH_REMATCH[1]}${BASH_REMATCH[2]^}; else out=$S; fi; printf '%s\n' "$out"
echo $foo
ein Beispiel für eine Situation, in der der Parser eine Liste von Wörtern erwartet . In Ihrem Fall sindecho ${F}
die Inhalte vonF
String-Split und Glob-Expanded. Das gilt auch für dasecho ${S:$N:1}
Beispiel und den Rest. Siehe BashPitfalls # 14 .