将文件名中所有以“.”分隔的部分的第一个字母转换为大写,Mac Bash 中最后一个字母除外

将文件名中所有以“.”分隔的部分的第一个字母转换为大写,Mac Bash 中最后一个字母除外

我想将 Mac Bash 中的文件名在每个点/句点后更改为首字母大写,文件扩展名除外。

  • 输入字符串示例:
    one.two.three.four.txt
    
  • 期望的输出:
    One.Two.Three.Four.txt
    

我尝试了以下方法:

echo 'one.two.three.four.txt' | awk 'BEGIN{FS=OFS="."} NF==1{$1=toupper($1)} {for (i=1;i<NF;i++) $i=toupper($i)} 1'

但这会导致输出:

ONE.TWO.THREE.FOUR.txt

所以它使所有内容都大写(扩展名除外)。

我正在寻找首字母大写、扩展名小写。

awk在 Mac Bash 中使用as寻找解决方案是sed \U行不通的(对我来说到目前为止还行不通)。

提前致谢

答案1

在您的尝试的变体中,应该执行以下操作:

echo "one.two.three.four.txt" |
     awk 'BEGIN{FS=OFS="."} {for (i=1;i<NF;i++) {$i=toupper(substr($i,1,1)) substr($i,2)}}1'

这将再次将输入和输出字段分隔符设置为..

然后,它将迭代除最后一个字段之外的所有字段,并将每个字段重新组装为第一个字符的大写版本(使用该substr()函数将其隔离)和原始内容的其余部分(再次使用substr()功能)。

最后,它将打印当前行,包括所有修改(这就是1规则块之外看似“流浪”的含义)。


附录:正如评论中所指出的,OP实际上不仅希望确保初始资本,而且希望确保成熟的资本大写- 分隔的.部分,即也强制所有后续字母为小写。这可以通过对上述程序进行微小修改来实现:

echo "one.two.tHREE.four.txt" |
     awk 'BEGIN{FS=OFS="."} {for (i=1;i<NF;i++) {$i=toupper(substr($i,1,1)) tolower(substr($i,2))}}1'

答案2

另一个 Perl 解决方案是使用一个简单的正则表达式:

echo "one-one.two_two.three.four.txt"|perl -pe 's/([\w-]+\.)/ucfirst($1)/ge'
One-one.Two_two.Three.Four.txt

这会重复 ( ) 查找由点字符分隔的\g带有或不带有 的一组单词字符。-使用\w自动暗示这_是该类中的有效字符。然后将每组的第一个字符 ( \e) 评估为小写。

答案3

你可以用 perl 来代替:

$ echo "one.two.three.four.txt" | 
    perl -F'\.' -lane 'print join ".", map{ucfirst}(@F);'
One.Two.Three.Four.Txt

为了避免扩展名的第一个字母也大写,您可以跳过最后一个.- 分隔的元素:

$ echo "one.two.three.four.txt" | 
    perl -F'\.' -lane 'print join( ".", map{ucfirst}(@F[0..$#F-1])) . ".$F[$#F]"'
One.Two.Three.Four.txt

答案4

然后安装 GNU sed:

$ echo 'one.two.three.four.txt' | sed -E 's/([^.])([^.]*\.)/\u\1\2/g'
One.Two.Three.Four.txt

相关内容