我有一个像这样的文本文件
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
答案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
。这意味着它将取代old
并new
控制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。