sed - làm thế nào để viết hoa mỗi từ thứ 3?


9

Được:

main_east_library
main_west_roof
main_north_roof
minor_south_roof

Làm thế nào tôi có thể sử dụng sed(đặc biệt là không awk, trvv) để tạo ra:

main_east_Library
main_west_Roof
main_north_Roof
minor_south_Roof

Cái gì đó như:

$ echo "main_west_library
main_west_roof
main_north_roof
minor_south_roof" | sed 's_\3_upcase(\3)_' 

Mặc dù điều đó mang lại:

sed: -e expression #1, char 16: Invalid back reference

1
không có awk hoặc tr sed của bạn sẽ thất bại nếu bạn thử nó trên một di sản hoặc chỉ hệ thống khác. Một số biểu thức trong câu trả lời là phần mở rộng GNU!
ikrabbe

Câu trả lời:


11

Với GNU sed:

sed -E 's/[[:alpha:]]+/\u&/3'

Sẽ viết hoa chuỗi thứ ba của các chữ cái từ mỗi dòng.

Để viết hoa mỗi chuỗi chữ cái thứ ba trong mỗi dòng:

sed -E 's/(([[:alpha:]]+[^[:alpha:]]+){2})([[:alpha:]]+)/\1\u\3/g'

Để viết hoa mỗi chuỗi chữ cái thứ ba trong toàn bộ đầu vào , với GNU awk:

awk -v RS='[^[:alpha:]]+' -v ORS= '
   NR % 3 == 0 {$0=toupper(substr($0,1,1)) substr($0,2)}
   {print $0 RT}'

Hoặc với perl:

perl -Mopen=locale -pe 's/\p{alpha}+/++$n % 3 == 0 ? "\u$&" : "$&"/ge'

Mặc dù [[:alpha:]]lớp ký tự có thể là một chút ngẫu nhiên trên một số hệ thống (ví dụ: trên các hệ thống GNU, bao gồm nhiều chữ số loại trừ các chữ Ả Rập (0123456789)), Perl \p{...}dựa trên các thuộc tính ký tự Unicode. Vì vậy, những người \p{alpha}sẽ bao gồm các chữ cái trong tất cả các bảng chữ cái và cả các ký tự chữ cái không chữ cái.

Nó sẽ không bao gồm kết hợp các dấu phụ mặc dù điều đó có nghĩa là các từ như Stéphanesẽ được coi là hai từ riêng biệt.

Vì vậy, bạn có thể muốn thay thế:

perl -Mopen=locale -pe 's/[\p{alpha}\p{mark}]+/++$n % 3 == 0 ? "\u$&" : "$&"/ge'

Mặc dù điều đó có thể kết thúc bao gồm quá nhiều.

Cũng lưu ý rằng trái với GNU sed, Perl \usẽ chuyển đổi chính xác các từ như fiddle(trong đó có một ký tự chữ ghép) thành Fiddle(2 ký tự Fi).


3

perl

perl -pe 's/(?:.*?_){2}\K./\u$&/'

Nó đếm 2 chuỗi ký tự kết thúc bằng dấu gạch dưới, sau đó viết hoa chữ cái tiếp theo.


2

Một GNU khác sed:

sed -E 's/([^[:alpha:]])([[:alpha:]])/\1\u\2/2'

Điều này giả định rằng dòng luôn bắt đầu bằng một từ.

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.