Meskipun lebih kompleks daripada jawaban skor terbaik, yang satu ini benar-benar melakukan hal itu: 'huruf pertama dalam variabel'. Jawaban skor terbaik tidak memiliki hasil itu. Sepertinya jawaban sederhana lebih dipilih secara sukarela daripada jawaban yang benar?
Krzysztof Jabłoński
15
@ KrzysztofJabłoński: Sebenarnya, "jawaban dengan skor terbaik" di bawah ini akan menghasilkan hasil yang sama dengan jawaban ini di bawah Bash 4. Jawaban ini memiliki overhead untuk memanggil subkulit (shell lain), overhead untuk memanggil utilitas 'tr' (proses lain , bukan Bash), overhead menggunakan di sini-doc / string (pembuatan file sementara) dan menggunakan dua substitusi dibandingkan dengan yang terbaik jawaban jawaban. Jika Anda benar-benar harus menulis kode lawas, pertimbangkan untuk menggunakan fungsi alih-alih subkulit.
Steve
2
Jawaban ini mengasumsikan input semua huruf kecil. Varian ini tidak memiliki asumsi: $ (tr '[: lebih rendah:]' '[: atas:]' <<< $ {foo: 0: 1}) $ (tr '[: atas:]' '[: lebih rendah: ] '<<< $ {foo: 1})
Itai Hanski
5
@ItaiHanski OP tidak menentukan apa yang harus terjadi pada karakter yang tersisa, hanya yang pertama. Seharusnya mereka ingin berubah notQuiteCamelmenjadi NotQuiteCamel. Varian Anda memiliki efek samping atau memaksa sisanya menjadi huruf kecil - dengan biaya menggandakan jumlah subkulit dan proses tr.
Jesse Chisholm
3
@DanieleOrlando, benar, tetapi pertanyaan ini tidak memiliki tag selain bash.
@ CMCDragonkai: Untuk huruf kecil huruf pertama, gunakan "${foo,}". Untuk huruf kecil semua huruf, gunakan "${foo,,}". Untuk huruf besar semua huruf, gunakan "${foo^^}".
Steve
1
Saya tidak sengaja memperhatikan itu ${foo~}dan ${foo~~}memiliki efek yang sama seperti ${foo^}dan ${foo^^}. Tetapi saya tidak pernah melihat alternatif itu disebutkan di mana pun.
mivk
5
ini sepertinya tidak berfungsi pada Mac. mendapatkan kesalahan berikut:bad substitution
Toland Hon
1
@TolandHon: Karena Anda mungkin sudah berolahraga, Anda harus meningkatkan ke versi 4.x, atau mencoba solusi lain jika mesin itu tidak dapat ditingkatkan karena alasan tertentu.
tidak berfungsi pada MacOS10 Lion, huh, \ u memperluas ke Anda alih-alih menjadi operator.
vwvan
2
@vwvan brew install coreutils gnu-seddan ikuti instruksi untuk menggunakan perintah tanpa awalan g. Untuk apa nilainya saya tidak pernah ingin menjalankan versi OSX dari perintah ini sejak mendapatkan versi GNU.
Dean
@vwvan: Ya, maaf, Anda membutuhkan GNU seddalam hal ini
Steve
2
@Dean: FWIW, saya tidak pernah ingin menjalankan OSX :-)
Steve
5
Cukup ubah sed 's/./\U&/dan akan berfungsi pada POSIX sed.
akhirnya sesuatu yang bekerja dengan variabel dan di Mac! Terima kasih!
OZZIE
4
@DanieleOrlando, tidak portabel seperti yang diharapkan. tr [:lower:] [:upper:]adalah pilihan yang lebih baik jika perlu bekerja dalam bahasa / lokal memasukkan huruf yang tidak ada dalam a-zatau A-Zrentang.
Ini dapat dilakukan dalam bash murni dengan bash-3.2 juga:
# 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}"
bagaimana cara mendefinisikan foo? Saya mencoba foo = $1tetapi saya hanya mendapatkan-bash: foo: command not found
OZZIE
1
@OZZIE, tidak ada spasi di sekitar =tugas dalam. Ini adalah sesuatu yang shellcheck.net akan temukan untuk Anda secara terprogram .
Charles Duffy
Saya selalu lupa bahwa tentang skrip shell .. hanya bahasa di mana satu spasi (sebelum / sesudah) penting ... sigh (python setidaknya 4 jika saya ingat dengan benar)
OZZIE
@OZZIE, itu memiliki untuk peduli, karena jika tidak masalah, Anda tidak bisa lulus =sebagai argumen untuk program (bagaimana cara seharusnya tahu jika someprogram =sedang berjalan someprogram, atau menugaskan ke variabel bernama someprogram?)
foo='one two three'; foo=$(for i in $foo; do echo -n "${i^} "; done) Resolusi lebih pendek untuk setiap kata. foo Sekarang adalah "One Two Three"
vr286
Bagaimana saya bisa menggunakan huruf besar 3 atau 4 pertama untuk huruf besar? Suka pqrs-123-v1 ke PQRS-123-v1 ? Atau Anda bisa mengatakan, semua huruf sebelum tanda hubung pertama ...
Vicky Dev
2
Alternatif dan solusi bersih untuk Linux dan OSX, dapat juga digunakan dengan variabel bash
Bagaimana jika karakter pertama bukan huruf (tetapi tab, spasi, dan kutipan ganda yang lolos)? Lebih baik kita menguji itu sampai kita menemukan surat! Begitu:
Silakan tulis kode bersih! Anda kekurangan kutipan di semua tempat. Anda menggunakan sintaks yang usang (backticks); Anda menggunakan sintaks antiquated ( $[...]). Anda menggunakan banyak tanda kurung yang tidak berguna. Anda mengasumsikan bahwa string terdiri dari karakter dari alfabet latin (bagaimana dengan huruf aksentuasi, atau huruf dalam huruf lain?). Anda memiliki banyak pekerjaan untuk membuat cuplikan ini dapat digunakan! (dan karena Anda menggunakan regex, Anda mungkin juga menggunakan regex untuk menemukan huruf pertama, bukan loop).
gniourf_gniourf
6
Saya pikir kamu salah. Ini adalah komentar wajib yang menyertai downvote, menjelaskan semua pola yang salah dan kesalahpahaman dari jawaban. Tolong, pelajari dari kesalahan Anda (dan sebelum itu, cobalah untuk memahaminya) daripada menjadi keras kepala. Menjadi orang baik juga tidak cocok dengan menyebarkan praktik buruk.
gniourf_gniourf
1
Atau, jika menggunakan Bash ≥4, Anda tidak perlu tr :if [[ $S =~ ^([^[:alpha:]]*)([[:alpha:]].*) ]]; then out=${BASH_REMATCH[1]}${BASH_REMATCH[2]^}; else out=$S; fi; printf '%s\n' "$out"
gniourf_gniourf
5
Kode ini masih rusak parah. Itu masih menggunakan backticks alih-alih sintaks substitusi modern; masih memiliki kutipan yang tak tertandingi; masih memiliki tanda kutip yang hilang di tempat-tempat di mana mereka sebenarnya penting ; dll. Cobalah memasukkan beberapa karakter glob yang dikelilingi ruang kosong ke dalam data pengujian Anda, jika Anda tidak percaya bahwa kutipan yang hilang itu membuat perbedaan, dan perbaiki masalah shellcheck.net ditemukan hingga kode ini muncul bersih.
Charles Duffy
2
Adapun bahasa yang Anda kutip dari unix.stackexchange.com/questions/68694/… , yang Anda lewatkan adalah echo $foocontoh situasi di mana pengurai mengharapkan daftar kata-kata ; jadi di Anda echo ${F}, isi Fstring-split dan glob-diperluas. Hal yang sama berlaku untuk echo ${S:$N:1}contoh dan yang lainnya. Lihat BashPitfalls # 14 .
Jawaban:
sumber
notQuiteCamel
menjadiNotQuiteCamel
. Varian Anda memiliki efek samping atau memaksa sisanya menjadi huruf kecil - dengan biaya menggandakan jumlah subkulit dan proses tr.bash
.Satu arah dengan bash (versi 4+):
cetakan:
sumber
"${foo,}"
. Untuk huruf kecil semua huruf, gunakan"${foo,,}"
. Untuk huruf besar semua huruf, gunakan"${foo^^}"
.${foo~}
dan${foo~~}
memiliki efek yang sama seperti${foo^}
dan${foo^^}
. Tetapi saya tidak pernah melihat alternatif itu disebutkan di mana pun.bad substitution
Satu cara dengan
sed
:Cetakan:
sumber
brew install coreutils gnu-sed
dan ikuti instruksi untuk menggunakan perintah tanpa awalang
. Untuk apa nilainya saya tidak pernah ingin menjalankan versi OSX dari perintah ini sejak mendapatkan versi GNU.sed
dalam hal inised 's/./\U&/
dan akan berfungsi pada POSIX sed.sumber
Berikut ini cara alat teks "asli":
sumber
tr [:lower:] [:upper:]
adalah pilihan yang lebih baik jika perlu bekerja dalam bahasa / lokal memasukkan huruf yang tidak ada dalama-z
atauA-Z
rentang.Hanya menggunakan awk
sumber
Ini dapat dilakukan dalam bash murni dengan bash-3.2 juga:
sumber
foo = $1
tetapi saya hanya mendapatkan-bash: foo: command not found
=
tugas dalam. Ini adalah sesuatu yang shellcheck.net akan temukan untuk Anda secara terprogram .=
sebagai argumen untuk program (bagaimana cara seharusnya tahu jikasomeprogram =
sedang berjalansomeprogram
, atau menugaskan ke variabel bernamasomeprogram
?)Ini juga berfungsi ...
Dan seterusnya.
Sumber:
Pengenalan / Tutorial:
sumber
Hanya menggunakan huruf kapital untuk kata pertama:
Untuk mengkapitalisasi setiap kata dalam variabel:
(bekerja di bash 4+)
sumber
foo='one two three'; foo=$(for i in $foo; do echo -n "${i^} "; done)
Resolusi lebih pendek untuk setiap kata. foo Sekarang adalah "One Two Three"Alternatif dan solusi bersih untuk Linux dan OSX, dapat juga digunakan dengan variabel bash
mengembalikan Abc
sumber
Yang ini bekerja untuk saya:
Mencari semua * file php di direktori saat ini, dan ganti karakter pertama dari setiap nama file dengan huruf kapital:
misal: test.php => Test.php
sumber
hanya untuk bersenang-senang di sini Anda berada:
sumber
Tidak persis apa yang diminta tetapi sangat membantu
Dan sebaliknya
sumber
first-letter-to-lower-xc () {v-first-letter-to-lower | xclip-clipboard pilihan}
sumber
Bagaimana jika karakter pertama bukan huruf (tetapi tab, spasi, dan kutipan ganda yang lolos)? Lebih baik kita menguji itu sampai kita menemukan surat! Begitu:
sumber
$[...]
). Anda menggunakan banyak tanda kurung yang tidak berguna. Anda mengasumsikan bahwa string terdiri dari karakter dari alfabet latin (bagaimana dengan huruf aksentuasi, atau huruf dalam huruf lain?). Anda memiliki banyak pekerjaan untuk membuat cuplikan ini dapat digunakan! (dan karena Anda menggunakan regex, Anda mungkin juga menggunakan regex untuk menemukan huruf pertama, bukan loop).tr
:if [[ $S =~ ^([^[:alpha:]]*)([[:alpha:]].*) ]]; then out=${BASH_REMATCH[1]}${BASH_REMATCH[2]^}; else out=$S; fi; printf '%s\n' "$out"
echo $foo
contoh situasi di mana pengurai mengharapkan daftar kata-kata ; jadi di Andaecho ${F}
, isiF
string-split dan glob-diperluas. Hal yang sama berlaku untukecho ${S:$N:1}
contoh dan yang lainnya. Lihat BashPitfalls # 14 .