bash sed 或 awk 中的字符串大写
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 
原文地址: http://stackoverflow.com/questions/11803395/
Warning: these are provided under cc-by-sa 4.0 license.  You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Capitalize strings in sed or awk
提问by GregB
I have three types of strings that I'd like to capitalize in a bash script. I figured sed/awk would be my best bet, but I'm not sure. What's the best way given the following requirements?
我想在 bash 脚本中使用三种类型的字符串。我认为 sed/awk 将是我最好的选择,但我不确定。鉴于以下要求,最好的方法是什么?
single word
e.g.taco -> Tacomultiple words separated by hyphens
e.g.my-fish-tacos -> My-Fish-Tacosmultiple words separated by underscores
e.g.my_fish_tacos -> My_Fish_Tacos
单字
例如taco -> Taco由连字符分隔的多个单词,
例如my-fish-tacos -> My-Fish-Tacos由下划线分隔的多个单词,
例如my_fish_tacos -> My_Fish_Tacos
回答by Paused until further notice.
There's no need to use capture groups (although &is a one in a way):
没有必要使用捕获组(尽管&在某种程度上是一个):
echo "taco my-fish-tacos my_fish_tacos" | sed 's/[^ _-]*/\u&/g'
The output:
输出:
Taco My-Fish-Tacos My_Fish_Tacos
The escaped lower case "u" capitalizes the next character in the matched sub-string.
转义的小写“u”将匹配子字符串中的下一个字符大写。
回答by Sergii Stotskyi
Using awk:
使用 awk:
echo 'test' | awk '{
     for ( i=1; i <= NF; i++) {
         sub(".", substr(toupper($i), 1,1) , $i);
         print $i;
         # or
         # print substr(toupper($i), 1,1) substr($i, 2);
     }
}'
回答by Andrew Clark
Try the following:
请尝试以下操作:
sed 's/\([a-z]\)\([a-z]*\)/\U\L/g'
It works for me using GNU sed, but I don't think BSD sed supports \Uand \L.
它对我使用 GNU sed 有效,但我认为 BSD sed 不支持\U和\L.
回答by alinsoar
Here is a solution that does not use the \u, that is not common to all seds.
这是一个不使用 的解决方案,它不是\u所有 sed 都通用的。
Save this file into capitalize.sed, then run sed -i -f capitalize.sed FILE
将此文件保存到capitalize.sed,然后运行sed -i -f capitalize.sed FILE
s:^:.:
h
y/qwertyuiopasdfghjklzxcvbnm/QWERTYUIOPASDFGHJKLZXCVBNM/ 
G 
s:$:\n:
:r
/^.\n.\n/{s:::;p;d}
/^[^[:alpha:]][[:alpha:]]/ {
    s:.\(.\)\(.*\):x: 
    s:\n\(..\):\nx: 
    tr
}
/^[[:alpha:]][[:alpha:]]/ {
    s:\n.\(.\)\(.*\)$:\nx:
    s:..:x:
    tr
}
/^[^\n]/ {
    s:^.\(.\)\(.*\)$:.:
    s:\n..:\n.:
    tr
}
回答by potong
This might work for you (GNU sed):
这可能对你有用(GNU sed):
echo "aaa bbb ccc aaa-bbb-ccc aaa_bbb_ccc aaa-bbb_ccc"  | sed 's/\<.\|_./\U&/g'
Aaa Bbb Ccc Aaa-Bbb-Ccc Aaa_Bbb_Ccc Aaa-Bbb_Ccc
回答by Neale Pickett
alinsoar's mind-blowing solution doesn't work at all in Plan9 sed, or correctly in busybox sed. But you should still try to figure out how it's supposed to do its thing: you will learn a lot about sed.
alinsoar 令人兴奋的解决方案在 Plan9 sed 中根本不起作用,或者在 busybox sed 中完全不起作用。但是您仍然应该尝试弄清楚它应该如何做它的事情:您将学到很多关于 sed 的知识。
Here's a not-as-clever but easier to understand version which works in at least Plan9, busybox, and GNU sed (and probably BSD and MacOS). Plan9 sed needs backslashes removed in the match part of the scommand.
这是一个不太聪明但更容易理解的版本,它至少适用于 Plan9、busybox 和 GNU sed(可能还有 BSD 和 MacOS)。Plan9 sed 需要在s命令的匹配部分删除反斜杠。
#! /bin/sed -f
y/PYFGCRLAOEUIDHTNSQJKXBMWVZ/pyfgcrlaoeuidhtnsqjkxbmwvz/
s/\(^\|[^A-Za-z]\)a/A/g
s/\(^\|[^A-Za-z]\)b/B/g
s/\(^\|[^A-Za-z]\)c/C/g
s/\(^\|[^A-Za-z]\)d/D/g
s/\(^\|[^A-Za-z]\)e/E/g
s/\(^\|[^A-Za-z]\)f/F/g
s/\(^\|[^A-Za-z]\)g/G/g
s/\(^\|[^A-Za-z]\)h/H/g
s/\(^\|[^A-Za-z]\)i/I/g
s/\(^\|[^A-Za-z]\)j/J/g
s/\(^\|[^A-Za-z]\)k/K/g
s/\(^\|[^A-Za-z]\)l/L/g
s/\(^\|[^A-Za-z]\)m/M/g
s/\(^\|[^A-Za-z]\)n/N/g
s/\(^\|[^A-Za-z]\)o/O/g
s/\(^\|[^A-Za-z]\)p/P/g
s/\(^\|[^A-Za-z]\)q/Q/g
s/\(^\|[^A-Za-z]\)r/R/g
s/\(^\|[^A-Za-z]\)s/S/g
s/\(^\|[^A-Za-z]\)t/T/g
s/\(^\|[^A-Za-z]\)u/U/g
s/\(^\|[^A-Za-z]\)v/V/g
s/\(^\|[^A-Za-z]\)w/W/g
s/\(^\|[^A-Za-z]\)x/X/g
s/\(^\|[^A-Za-z]\)y/Y/g
s/\(^\|[^A-Za-z]\)z/Z/g

