如果任何第一个英文字母是小写,则将其大写

如果任何第一个英文字母是小写,则将其大写

我有一个 Markdown 文档myfile.md,其中包含英语句子列表,其中一些首字母小写,一些首字母大写。
所有英文句子均以标准英文字母开头;不使用特殊字符:

x
x
x

我需要一个符合该逻辑的函数:
如果任何第一个英文字母是小写,则将其大写

因此,要将文件更改为如下所示:

X
X
X


我尝试过的

1)tr

我想尝试使用tr正则表达式来做到这一点,'tr '[:lower:]' '[:upper:]' myfile.md 但我既没有找到一种将正则表达式组合在 中的方法tr,也没有找到一种用 来处理文件内数据的方法tr
相反,我只找到了一种在 shell 提示符中转换文本的方法,如下所示:

echo x | tr '[:lower:]' '[:upper:]'

X

2)sed

sed 's/^[a-z]*/[A-Z]/' myfile.md
sed -r 's/^[a-z]*/[A-Z]/' myfile.md

但执行后,myfile.md仍然包含

x
x
x

反而:

X
X
X

我的问题

如何在不使用任何 CLUI 文本编辑器(例如nano或)的情况下使用 shell 中描述的逻辑vim

答案1

使用\UGNU sed 中的函数。

 s/^\([a-z]\)/\U\1/

因此,如果该字符是小写,则捕获行开头的单个字符,如果该字符是大写,则捕获该字符。

由于 \U 不理会其他事物,因此可以简化为

s/\(.\)/\U\1/

因为.将会匹配该行的第一个字符(如果有)。

答案2

tr在这里不会帮助你,因为大写的tr会变成全部字符转换为大写(tr仅具有一次字符上下文,因此它永远不会知道“行首”或“单词开头”)。

sed如果你使用 GNU 就可以做到sed。但是,您显示的方式将用文字文本替换第一个大写字符[A-Z]


由于这个问题被标记为,这是一个符合标准的awk解决方案,它将简单地将任意行上的第一个字符大写:

awk '{ ch = toupper(substr($0,1,1)); sub(".", ""); $0 = ch $0; print }' file

awk命令正在执行的操作是使用 提取该行的第一个字符substr()。然后将其大写并将其分配给变量ch。然后使用删除该行上的第一个字符sub(),并将大写字母ch添加到该行前面。然后打印该行。

测试这个:

$ cat file
Apple
orange
grapefruit
Mango
$ awk '{ ch = toupper(substr($0,1,1)); sub(".", ""); $0 = ch $0; print }' file
Apple
Orange
Grapefruit
Mango

如果数据有一些缩进(即行开头有空格),则使用

awk '{ ch = toupper(substr($1,1,1)); sub(".", "", $1); $1 = ch $1; print }' file

(但这会消除缩进)。


如果您愿意使用 Perl 来执行此操作,则以下代码会将每行的第一个字符大写,其方式与awk上面第一个程序的执行方式类似。

perl -pe 'substr($_,0,1,uc(substr($_,0,1)))' file

虽然使用

perl -pe 's/^./\U$&/' file

会更短并且更“像 Perl”。

^.在该表达式中替换[^[:blank:]]为 来替换该行中的第一个非空白字符(这将保存任何缩进)。

答案3

如果您想将行中的第一个非空白字符大写(如果它是字母),请使用此变体拘萨罗南达的回答

awk '{ ch = substr($1,1,1); uch = toupper(ch); if (ch != uch) sub(ch, uch); print }'

请注意,这不会破坏空间。


如果您想将行中的第一个字母大写,请使用此变体伊卡洛斯的回答

sed 's/\([a-z]\)/\U\1/'

即,省略^.

答案4

POSIX sed:

h
s/(.).*/\1/
y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/
G
s/(.)\n.?(.*)/\1\2/

相关内容