将 ] 之后的第一个字母更改为大写

将 ] 之后的第一个字母更改为大写

我有一个 CSV 文件,其中有数千行,如下所示:

bla bla blab [FR] john is bla bla
bla [US] blue house in Chicago...
[ES] accessing the safe... bla bla

看到 之间的元素了[ ]吗?这些元素后面总是跟有空格和新短语的开头。我想将空格后找到的第一个字母转换为大写,使文件像

bla bla blab [FR] John is bla bla
bla [US] Blue house in Chicago...
[ES] Accessing the safe... bla bla

我如何从终端、使用 sed、awk 或其他方式做到这一点?

请解释一下解决方案,我想理解和学习。

谢谢。

答案1

POSIXly,你可以这样做:

awk -F '] ' '{
  out = $1
  for (i = 2; i <= NF; i++)
    out = out FS toupper(substr($i, 1, 1)) substr($i, 2)
  print out}' < infile

或者:

awk '
  BEGIN {FS = OFS = "] "}
  {
    for (i = 2; i <= NF; i++)
      $i = toupper(substr($i, 1, 1)) substr($i, 2)
    print
  }' < infile

这定义"] "F字段分隔符,在转换每个字段的第一个字符(从nd 开始直到字段数)后S,我们将字段重新连接在一起。2NFNFto upper

(但请注意,包括FreeBSD 在内的一些awk实现(也可能是 macOS)尚未国际化,因此无法更改为(或更改为if以其预组合形式 (U+00E9) 表示)。mawkawk[GR] π[GR] Π[FR] éric[FR] Éricé

答案2

如果在 GNU 系统上,您可以使用sed

sed 's/] ./\U&/g' <infile

s特雷姆编辑伊托尔s替代/替换什么/用。。。来代替/G全局'<输入文件

这里 ”替换什么" 是一个文字],后跟一个空格,然后是一个字符 (.匹配除 ewline 之外的单个字符,但如果在模式空间中找到了 ewline 字符,\n则将匹配ewline 字符。在 中,除非将标志添加到正则表达式,否则不会匹配.)\nperls

替换什么" is \U&,在 sed 中是对“replace-what”部分(代表)&的反向引用,因此会将匹配的部分替换为大写。\U\Upper-case\U&


如果您sed不是 GNU sed,您可以使用以下命令执行相同操作perl

perl -Mopen=locale -pe 's/] ./\U$&/g' < infile

答案3

首先,您可以设置 FS: -v FS="[]][[:space:]]+"ie,[]]然后设置[[:space:]]+.这样您就可以获得进行更改的字段:

$ awk -v FS="[]][[:space:]]+" '{print  $2}' file
john is bla bla
blue house in Chicago...
accessing the safe... bla bla

这里你“想将空格后找到的第一个字母转换为大写”,所以你可以测试:

awk -v FS="[]][[:space:]]+" '{print toupper(substr($2,1,1))substr($2,2)}'  file

John is bla bla
Blue house in Chicago...
Accessing the safe... bla bla

并打印全部:

$ awk -v FS="[]][[:space:]]+" '{print $1, toupper(substr($2,1,1))substr($2,2)}'  file
bla bla blab [FR John is bla bla
bla [US Blue house in Chicago...
[ES Accessing the safe... bla bla

但您看到一个问题:分隔符的字符丢失了。在这些情况下,我们可以使用函数的第四个参数split()并插入FS到函数中。因此,您可以获得更改和所需的输出:

awk -v FS="[]][[:space:]]+" '                                              
{
split($0, a, FS, seps)
a[i]=$1
a[2]= toupper(substr($2,1,1))substr($2,2)
for (i=1; i<=NF; i++)
printf "%s%s", a[i], seps[i]
print ""
  }
' file
bla bla blab [FR] John is bla bla
bla [US] Blue house in Chicago...
[ES] Accessing the safe... bla bla

感谢埃德莫顿代码:https://stackoverflow.com/a/22211988在这里您可以看到详细信息。

相关内容