Bagaimana cara mengganti argumen baris perintah?


125

Saya mencari SO dan menemukan bahwa huruf besar mengikuti string akan bekerja

str="Some string"
echo ${str^^}

Tapi saya mencoba melakukan hal serupa pada argumen baris perintah, yang memberi saya kesalahan berikut

Mencoba

#!/bin/bash
             ## Output
echo ${1^^}  ## line 3: ${1^^}: bad substitution
echo {$1^^}  ## No error, but output was still smaller case i.e. no effect

Bagaimana kita bisa melakukan ini?


8
Ini berfungsi baik untuk saya . Posting seluruh naskah Anda, kesalahannya mungkin di tempat lain. Apakah shebang Anda menunjuk ke bash?
manatwork

Jawaban:


151

Sintaks str^^yang Anda coba tersedia dari Bash 4.0 ke atas. Mungkin versi Anda yang lebih lama (atau Anda menjalankan skrip dengan shsecara eksplisit):

Coba ini:

str="Some string"
printf '%s\n' "$str" | awk '{ print toupper($0) }'

1
Dari kata-kata mtk saya mengerti bahwa modifikasi kasus benar-benar bekerja untuknya dengan variabel.
manatwork

1
@manatwork Itu tidak secara jelas dinyatakan dalam pertanyaan awal. Pesan kesalahan substitusi buruk sama dengan yang Anda dapatkan dengan versi bash yang lebih lama.
Bernhard

4
Anda benar. Saya memeriksa versinya, 3.2.25. Solusi Anda berhasil dan saya juga sudah mencoba tr '[a-z]' [[A-Z]'.
mtk

20
@ mtk Seharusnya begitu tr '[a-z]' '[A-Z]'.
l0b0

2
Saya sedang menjalankan GNU bash, version 4.3.42(1)-release (x86_64-apple-darwin14.5.0), dan saya mendapatkan kesalahan yang sama seperti OP, jadi saya tidak berpikir ini tersedia pada bash4.0 dan di atas seperti yang Anda katakan.
Heath Borders

79
echo "lowercase" | tr a-z A-Z

Keluaran:

LOWERCASE

1
Saya pikir POSIX tidak memerlukan /seperti pada tr /a-z/ /A-Z/sebelum edit saya: ini hanya berfungsi karena diganti /oleh /tetapi tidak berguna: pubs.opengroup.org/onlinepubs/9699919799/utilities/tr.html Ada juga ada yang lebih jelas dan kurang bermanfaat tr '[:lower:]' '[:upper:]'.
Ciro Santilli 新疆 改造 中心 法轮功 六四 事件

Benar. tr sangat berbeda, tetapi berfungsi.
Doug

umlaut tidak bekerja dengan ini.
Evgeny

22

Hati-hati dengan tr kecuali AZ yang Anda gunakan. Untuk lokal lain bahkan '[: bawah:]' '[: atas:]' gagal, hanya toupper dan bash (v4 +) yang berfungsi

$ str="abcåäö"
$ echo "$str"|tr '/a-z/' '/A-Z/'
ABCåäö
$ echo "$str"|LC_ALL=sv_SE tr '[:lower:]' '[:upper:]'
ABCåäö
$ echo "$str"|awk '{print toupper($0)}'
ABCÅÄÖ
$ echo ${str^^} # Bash 4.0 and later
ABCÅÄÖ
$ STR="ABCÅÄÖ"
$ echo ${STR,,}
abcåäö

1
FWIW, tr '[:lower:]' '[:upper:]'sekarang berfungsi untuk contoh Anda di OS X setidaknya (juga dengan LC_ALL=sv_SE)
Ethan

1

Atau, Anda bisa beralih ke ksh atau zsh yang memiliki kasus dukungan konversi selama puluhan tahun (jauh sebelum bash's ${var^^}ditambahkan dalam 4.0), meskipun dengan sintaks yang berbeda:

#! /bin/ksh -
typeset -u upper="$1"
printf '%s\n' "$upper"

(juga berfungsi dengan zsh; perhatikan bahwa dalam pdksh / mksh, itu hanya berfungsi untuk huruf ASCII).

Dengan zsh, Anda juga dapat menggunakan Uflag ekspansi parameter:

#! /bin/zsh -
printf '%s\n' "${(U)1}"

POSIXLY, Anda dapat menggunakan:

awk 'BEGIN{print toupper(ARGV[1])}' "$1"

Ada juga:

printf '%s\n' "$1" | tr '[:lower:]' '[:upper:]'

Tetapi dalam beberapa implementasi, termasuk GNU tr, itu hanya berfungsi untuk karakter single-byte (jadi di lokal UTF-8, hanya pada huruf ASCII).


0

Jika seseorang masih mendapatkan kesalahan saat mencoba ${str^^}, Anda dapat mencoba python -catau perlKemungkinan karena versi bash lebih rendah dari 4.

Tapi, sejauh ini bash 4 atau lebih bekerja dengan cepat dengan solusi yang ada.

L2U="I will be upper"

Menggunakan python -cdi bash

python -c "print('$L2U'.upper())"
I WILL BE UPPER

Demikian pula itu juga dapat digunakan untuk bermodalkan :

service="bootup.sh on home"
python -c "print('$service'.capitalize())"
Bootup.sh on home

Menggunakan perl

echo $L2U | perl -ne 'print "\U$_"'
I WILL BE UPPER
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.