如何将某个字符前的字母大写?(^)

如何将某个字符前的字母大写?(^)

我想转换这个:

foo^bar
ba^rfoo
oofrab
raboof^

对此:

FOObar
BArfoo
oofrab
RABOOF

“^”(或其他特殊字符,如果方便的话)之前的任何字符都大写

此外,如果这样做更容易的话,也不需要删除“^”。

答案1

使用 GNU sed(Ubuntu 的默认设置)(感谢 pabouk 提供的-r选项建议):

< inputfile sed -r 's/^(.*)\^/\U\1\E/' > out

使用perl(感谢 Oli 提供的缩短正则表达式):

< inputfile perl -pe 's/^(.*)\^/\U\1\E/' > out

命令 #1 分解

  • < inputfile:将内容重定向inputfilestdin
  • -r:允许使用扩展正则表达式
  • > out:将内容重定向stdoutout

命令 #2 分解

  • < inputfile:将内容重定向inputfilestdin
  • > out:将内容重定向stdoutout

正则表达式细分

  • s:执行替换
  • /: 启动正则表达式
  • ^: 匹配行首
  • (:开始第一个捕获组
  • .*: 匹配任意数量的字符
  • ):停止第一个捕获组
  • \^: 匹配一个^字符
  • /:停止正则表达式/开始替换
  • \U: 开始转换为大写
  • \1: 替换为第一个捕获组
  • \E: 停止转换为大写
  • /:停止替换

答案2

使用vim

vim -es '+g/\^/normal gUf^' +wq foo
  • 打开-es令人尊敬的 ex 模式,并使 vim 静音(大部分)。
  • +用于提供 vim 命令作为命令行参数。
  • g/\^/- 在所有匹配的行上运行命令/\^/
  • normal- 将命令的其余部分作为正常模式操作运行。
  • gUf^- 转换为大写(gU)直到^f^)。在这种情况下使用范围时g/.../,在执行命令之前,光标将放在每行的开头。
  • 然后保存并退出(wq)。

f查找第一个^,因此具有多个 的行将^仅转换字段。没有简单的动作可以找到最后一个^。您可以尝试转到行尾并向后搜索($F^),但如果是最后一个字符,则该操作将失败^。因此,您需要分两步进行:

vim -es '+g/\^./norm $F^gU0' '+g/\^$/norm gU$' +wq foo

答案3

编辑

大约一个半小时后,我想到了这个:

awk -F' ' '{ gsub(/\^/,"@ "); for (i=1;i<=NF;i++){ if($i ~ /\@/) $i = toupper($i);};gsub("@ ","");gsub("@",""); print   }  ' removecharsfile 

基本思想:

  • 删除 ^ 并用 @ 加空格替换
  • 将空格视为字段分隔符;现在我们有字段可以使用了
  • for 循环遍历每一行中的每个字段,并检查是否有 @ 字符。
  • 如果有 @ 字符,则将该字段转换为大写。为什么 $i = toupper($i) ?因为否则它不会存储在任何地方
  • 循环完成后,删除@+空格,以及字段末尾的任何@。
  • 打印所有内容

也许将所有这些写在一行上的更好方法是将其放在一个文件中(整齐地组织在下面),然后像这样用 awk 运行它awk -f awkscript theinputfile

# awk script to capitalize
# whatever comes before caret(^)


{
  gsub (/\^/, "@ ");
  for (i = 1; i <= NF; i++)
    {
      if ($i ~ /\@/)
        $i = toupper ($i);
    };
  gsub ("@ ", "");
  gsub ("@", "");
  print

}

实际运行如下:

在此处输入图片描述

原始帖子

我将用 awk 贡献我自己的代码版本:

awk -F'^' '{print toupper($1)$2}' thefile

当然,您可以使用> output.txt 以下方法重定向输出:

在此处输入图片描述

答案4

Bash 也可以做到这一点,因此我将把 bash 答案加入到其中。

#bash
while IFS= read -r line; do
    if [[ $line = *^* ]]; then
        tmp=${line%%^*} 
        line=${tmp^^}${line#*^}
    fi
    printf '%s\n' "$line"
done < inputfile > outptufile

这只是逐行迭代输入文件(Bash常见问题 1),并使用参数扩展进行拆分和大写(Bash常见问题 73)。

相关内容