Làm thế nào để viết hoa đối số dòng lệnh?


125

Tôi đã tìm kiếm SO và thấy rằng viết hoa một chuỗi sau sẽ hoạt động

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

Nhưng tôi đã cố gắng làm một điều tương tự trên một đối số dòng lệnh, điều này cho tôi lỗi sau

Đã thử

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

Làm thế nào chúng ta có thể làm điều này?


8
làm việc cho tôi tốt. Đăng toàn bộ tập lệnh của bạn, lỗi có thể ở nơi khác. Là shebang của bạn chỉ vào bash?
manatwork

Câu trả lời:


151

Cú pháp str^^mà bạn đang thử có sẵn từ Bash 4.0 trở lên. Có lẽ phiên bản cũ hơn của bạn (hoặc bạn đã chạy tập lệnh shmột cách rõ ràng):

Thử đi:

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

1
Từ những lời của mtk tôi hiểu rằng việc sửa đổi trường hợp thực sự có hiệu quả với anh ta với các biến.
manatwork

1
@manatwork Điều đó không được nêu rõ trong câu hỏi ban đầu. Thông báo lỗi thay thế xấu giống như bạn nhận được với các phiên bản bash cũ hơn.
Bernhard

4
Bạn nói đúng. Tôi đã kiểm tra phiên bản, phiên bản 3.2.25 của nó. Giải pháp của bạn hoạt động và tôi cũng đã thử tr '[a-z]' [[A-Z]'.
mtk

20
@mtk Điều đó nên tr '[a-z]' '[A-Z]'.
l0b0

2
Tôi đang chạy GNU bash, version 4.3.42(1)-release (x86_64-apple-darwin14.5.0), và tôi nhận được lỗi tương tự như OP, vì vậy tôi không nghĩ rằng đây là có sẵn trên bất kỳ bash4.0 và ở trên như bạn nói.
Heath

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

Đầu ra:

LOWERCASE

1
Tôi nghĩ POSIX không yêu cầu /như tr /a-z/ /A-Z/trước khi chỉnh sửa của tôi: điều này chỉ hoạt động vì nó thay thế /bởi /nhưng vô dụng: pubs.opengroup.org/onlinepub/9699919799/utilities/tr.html Cũng tồn tại nhiều thứ tối nghĩa và ít hữu dụng hơn tr '[:lower:]' '[:upper:]'.
Ciro Santilli 心 心

Chính xác. tr rất khác nhau, nhưng nó hoạt động.
Doug

umlauts không làm việc với điều này.
Evgeny

22

Hãy cẩn thận với tr trừ khi AZ là tất cả những gì bạn sử dụng. Đối với các địa phương khác, thậm chí '[: Lower:]' '[: Upper:]' không thành công, chỉ có toupper và bash (v4 +) của awk hoạt động

$ 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:]'hiện đang làm việc cho ví dụ của bạn trên OS X ít nhất (cũng với LC_ALL=sv_SE)
Ethan

1

Ngoài ra, bạn có thể chuyển sang ksh hoặc zsh mà đã hỗ trợ chuyển đổi trường hợp trong nhiều thập kỷ (lâu trước khi bash's ${var^^}gia tăng trong 4.0), mặc dù với một cú pháp khác nhau:

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

(cũng hoạt động với zsh; lưu ý rằng trong pdksh / mksh, chỉ hoạt động với các chữ cái ASCII).

Với zsh, bạn cũng có thể sử dụng Ucờ mở rộng tham số:

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

POSIXLY, bạn có thể sử dụng:

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

Ngoài ra còn có:

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

Nhưng trong một vài triển khai, bao gồm GNU tr, chỉ hoạt động đối với các ký tự byte đơn (vì vậy trong các ngôn ngữ UTF-8, chỉ trên các chữ cái ASCII).


0

Nếu ai đó vẫn gặp lỗi khi thử ${str^^}, bạn có thể thử python -choặc perlcó thể vì phiên bản bash thấp hơn 4.

Nhưng, cho đến nay bash 4 trở lên đang hoạt động nhanh chóng với giải pháp hiện có.

L2U="I will be upper"

Sử dụng python -ctrong bash

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

Tương tự, nó cũng có thể được sử dụng để viết hoa với:

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

Sử dụng perl

echo $L2U | perl -ne 'print "\U$_"'
I WILL BE UPPER
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.