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?

mtk
sumber
8
Ini berfungsi baik untuk saya . Posting seluruh naskah Anda, kesalahannya mungkin di tempat lain. Apakah shebang Anda menunjuk ke bash?
manatwork
mungkin sama dengan: stackoverflow.com/questions/2264428/…
Ciro Santilli 新疆 改造 中心 法轮功 六四 事件

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) }'
Guru
sumber
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
Johner Ramirez
sumber
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åäö
lpaseen
sumber
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).

Stéphane Chazelas
sumber
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
Rakib Fiha
sumber