对于文本文件的每一行,将分号后面的第一个字符设为大写

对于文本文件的每一行,将分号后面的第一个字符设为大写

我有一个像这样的文本文件

John Doe;john Doe is ...;he lives in ...
Mike Nelson;mike Nelson works for ...;he makes ...
Marcy William;marcy's mother is ...;marcy travels a lot... 

我想将分号后面的每个字符转换为大写,所以最终结果是

John Doe;John Doe is ...;He lives in ...
Mike Nelson;Mike Nelson works for ...;He makes ...
Marcy William;Marcy's mother is ...;Marcy travels a lot...

保持其余部分完好无损。

该文件包含重音字母并以 UTF-8 编码。

答案1

GNU Sed:

sed 's/;[[:lower:]]/\U&/g' file

对于分号 ( ;[[:lower:]]) 后面的每个小写字符,我们将其设为大写\U特殊序列。该g标志替换一行中所有出现的位置。

如果 GNU Sed 不可用,则可以使用符合 POSIX 的替代方案前任

printf '%s\n' '%s/;[[:lower:]]/\U&/g' '%p' | ex file

替代命令是相同的,但所有行都应该用 来寻址%%p打印输出。如果您想直接修改该文件,%p请将x.

答案2

不是 awk 或 sed,而是 perl:

perl -C -pe 's/;(.)/;\u$1/g'

-C选项根据您的区域设置环境变量(LC_ALL等)打开或关闭 UTF-8 i/o;如果您希望它无条件地采用 UTF-8 输入和输出,请将其更改为-CSD.

请注意,Unicode 大小写很棘手。那将会转伊赫桑进入伊赫桑而不是正确的伊赫桑(土耳其语名字即使是大写字母,在 i 上方也有一个点)。

答案3

这是一种方法,使用 perl:

perl -C -pe 's/;(.)/";" . uc($1)/eg' file

由于您在输入文件中没有显示任何重音符号,因此我使用它进行测试:

$ cat file
John Doe;john Doe is ...;he lives in ...
Mike Nelson;mike Nelson works for ...;he makes ...
Émilie du Châtelet;émilie du Châtelet;works for ...;she makes ...
Marcy William;marcy's mother is ...;marcy travels a lot...
Άσπα Κυριάκου;άσπα's brother is ...; άσπα likes fish

其产生:

$ perl -C -pe 's/;(.)/";" . uc($1)/eg' file
John Doe;John Doe is ...;He lives in ...
Mike Nelson;Mike Nelson works for ...;He makes ...
Émilie du Châtelet;Émilie du Châtelet;Works for ...;She makes ...
Marcy William;Marcy's mother is ...;Marcy travels a lot...
Άσπα Κυριάκου;Άσπα's brother is ...; άσπα likes fish

解释

  • -C:(man perlrun详细信息请参阅)本质上,这启用了 utf8。
  • -pe:逐行读取输入文件,并在应用 给出的脚本后打印每一行e

这项工作发生在替换运算符中,其一般格式为s/old/new/flags。这意味着它将取代oldnew控制flags它的工作方式。这里,使用的标志是e在替换中启用 Perl 代码,g这意味着“应用于该行的所有匹配”。

捕获;(.)a 之后找到的每个字符;并将其保存为$1.然后我们将其替换为 a ;,并将字符转换为大写 ( uc($1))。

答案4

使用 Raku(以前称为 Perl6)

Perl6/Raku 项目的一个优点是它被设计为从头开始优雅地处理 Unicode。感谢@terdon 发布了一个很好的测试文件:

~$ raku -pe 's:g/ \;(.) /;{$0.uc}/;'  terdon_uni.txt
John Doe;John Doe is ...;He lives in ...
Mike Nelson;Mike Nelson works for ...;He makes ...
Émilie du Châtelet;Émilie du Châtelet;Works for ...;She makes ...
Marcy William;Marcy's mother is ...;Marcy travels a lot...
Άσπα Κυριάκου;Άσπα's brother is ...; άσπα likes fish

上面我们看到分号后第一个字符的捕获。标志:g( 的缩写:global)移动到运算符的头部s///,因此我们从一开始就知道我们正在寻找什么样的匹配。注意 Raku start $0$1$2等中的捕获。运算符的“匹配”(左)一半s///是空白容忍的,这提高了可读性。运算符的“替换”(右)部分s///用于{…}指示关闭。

下面我使用 Raku 的<(…)>捕获标记。 Raku 的<(…)>外接符相当于 Perl5 的\K标志。进行了一场比赛,但<(…)>标记告诉 Raku 将外面的所有东西都扔掉<(…)>,并将内部(捕获)加载到 中$/。由于 Raku 执行整个匹配,但仅捕获您想要更改的确切字符,因此大大简化了替换的编写:

~$ raku -pe 's:g/ \; <(.)> /{$/.uc}/;'  terdon_uni.txt
John Doe;John Doe is ...;He lives in ...
Mike Nelson;Mike Nelson works for ...;He makes ...
Émilie du Châtelet;Émilie du Châtelet;Works for ...;She makes ...
Marcy William;Marcy's mother is ...;Marcy travels a lot...
Άσπα Κυριάκου;Άσπα's brother is ...; άσπα likes fish

HTH。

https://raku.org

相关内容