我想将 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