如何使用shell脚本大写每个句子中第一个单词的第一个字母?

Adr*_*rge 5 scripts

我试图从一个名为 input.txt 的 txt 文件中将每个句子中第一个单词的每个首字母大写,我希望这个输入文件成为 shell 脚本的参数

 ./script.sh input.txt
Run Code Online (Sandbox Code Playgroud)

示例输入文件:

i am Andrew. you are Jhon. here we are, forever.
Run Code Online (Sandbox Code Playgroud)

结果文件:

I am Andrew. You are Jhon. Here we are, forever.
Run Code Online (Sandbox Code Playgroud)

一个特例。如果我们的文本是(与@RaduRadeanu 答案相关)怎么办

i am andrew. you
are jhon. here we are
forever
Run Code Online (Sandbox Code Playgroud)

结果将是:

I am andrew. You
Are jhon. Here we are
Forever.
Run Code Online (Sandbox Code Playgroud)

所以它将每个句子的每个第一个单词以及换行的每个第一个单词转换为大写。我们如何跳过新行的大写第一个单词?

所以正确的结果应该是:

I am andrew. You
are jhon. Here we are
forever.
Run Code Online (Sandbox Code Playgroud)

如果句子以“?”结束怎么办?或者 ”!” ???

Rad*_*anu 4

sed命令对于从 shell 脚本编辑文件来说非常强大。借助它的帮助,您可以根据需要编辑文本文件。话虽这么说,下面的脚本可以做你想做的事:

#!/bin/bash

#check if a file is given as argument
if [ $# -ne 1 ];then
  echo "Usage: `basename $0` FILE NAME"
  exit 1
fi

sed -i 's/^\s*./\U&\E/g' $@         #capitalize first letter from a paragraf/new line
sed -i 's/[\.!?]\s*./\U&\E/g' $@    #capitalize all letters that follow a dot, ? or !
Run Code Online (Sandbox Code Playgroud)

对于你的特殊情况,事情变得稍微:

#!/bin/bash

#check if a file is given as argument
if [ $# -ne 1 ];then
  echo "Usage: `basename $0` FILE NAME"
  exit 1
fi

sed -i '1s/^\s*./\U&\E/g' $@  #capitalize first letter from the file
sed -i 's/\.\s*./\U&\E/g' $@  #capitalize all letters that follow a dot

#check if the a line ends in dot, ? or ! character and 
#if yes capitalize first letter from the next line
next_line=0
cat $@ | while read line ;do
  next_line=$[$next_line+1]
  lastchr=${line#${line%?}}
  if [ "$lastchr" = "." ] || [ "$lastchr" = "!" ] || [ "$lastchr" = "?" ]; then
    sed -i "$[$next_line+1]s/^\s*./\U&\E/g" $@
  fi
done
Run Code Online (Sandbox Code Playgroud)

另外,您可以参考本教程:Unix - Regular Expressions with SED以了解如何在这些情况下工作。