如何在bash中将每行的第一个字母大写?

3

我正在寻找一条在bash中将每行的首字母大写的命令。

实际上,我使用了这个命令:

sed 's/^\(.\)/\U\1/'

但我需要使用另一个命令,而不是“\U”。

3
为什么不能使用\U - choroba
2
关于“我需要使用另一个命令而不是"\U"”,为了避免浪费时间建议,您不能使用哪些其他完全合理的解决方案?您有其他非显而易见的要求吗(例如,它不能是perl,或者必须是sed,或者不能是GNU sed,或者只能是shell内置命令,或者只能是sed或awk等)?你的行是否总是以字母开头,还是可以以数字或标点符号开头,如果是这样,你想要发生什么?[编辑]您的问题以包括简明、可测试的示例输入和预期输出以及您的完整要求。 - Ed Morton
@Pedro,只有这个回答https://dev59.com/WWLVa4cB1Zd3GeqPvE9k#10008858符合要求。 - Walter A
3个回答

9

为什么需要使用除了\U之外的内容?

您可以使用只大写一个字母的\u

sed 's/./\u&/'

或者,使用参数扩展:
while read line ; do echo "${line^}" ; done

这是一项任务 - 我们被要求不使用任何'\u'或'\U'。导师要求我们使用类似于'[:upper:]'的东西。我只是找不到其他表示方法了。 - morkan
1
[:upper:] 是 POSIX 字符类,用于正则表达式中以一种与语言环境无关的方式匹配大写字母。它与将字母转换为大写字母无关。 - Ed Morton
1
这似乎是GNU扩展。它不能与例如BSD sed一起使用。 - robx

1

将文件按第一个字符/行的其余部分拆分,将第一个字符大写并将列粘贴在一起。

paste -d "" <(cut -c1 inputfile| tr '[:lower:]' '[:upper:]') <(cut -c2- inputfile)

编辑:
当您想要从流中解析输入(例如mycommand | myscript.sh)时,我的原始解决方案会导致问题。我的解决方案想要对输入进行两次解析。当您可以等待输入过程完成时,可以将输出重定向到临时文件。

tmpfile=/tmp/myscript.wrk
# read input with cat
cat > ${tmpfile}
paste -d "" <(cut -c1 ${tmpfile}| tr '[:lower:]' '[:upper:]') <(cut -c2- ${tmpfile})
rm -f ${tmpfile} 2>/dev/null

您可以在命令行上尝试相同的操作。没有等待时间,第二个“cut”将找到一个空文件。当原始命令运行超过一秒钟时,1秒的等待时间将失败。

mycommand | tee /tmp/dont_do_this | 
   cut -c1 | tr '[:lower:]' '[:upper:]' | 
   paste -d "" - <(sleep 1;cut -c2- /tmp/dont_do_this)

回顾以上解决方案,可以得出结论,你应该使用像@choroba发布的解决方案。当讲师说你应该使用[:lower:]时,就像问你是否想喝咖啡并补充说你应该从鼻子喝一样:可能但不好。如果你真的想这样做,请尝试下一个解决方案:
mycommand | while read -r line; do
   printf "%s%s\n" $(tr '[:lower:]' '[:upper:]' <<< "${line:0:1}") "${line:1}"
done

这正是我在寻找的 - 只需使用粘贴命令即可。我只需要从标准输出获取它,而不是从文件中获取。我应该如何编写它? - morkan
使用标准输入需要采用不同的方法。拆分输入并连接两个线程需要采用基于行的方法。或者使用awk - Walter A

-1

这是一种简单有效的方法: sed -e 's/^./\U&/' yourfile


OP说:“但我需要使用另一条命令而不是“\U”。”。 - George Vasiliou

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接