String 如何:在Bash中按照标题大小写规则转换文本

String 如何:在Bash中按照标题大小写规则转换文本,string,bash,awk,sed,tr,String,Bash,Awk,Sed,Tr,如何在遵循规则的同时将字符串转换为标题大小写,而不仅仅是将单词的每个首字母大写 示例规则: 除以下文字外,所有文字均大写: 将所有冠词(a,the)、介词(to、at、in、with)和并列连词(and、but、or)小写 将标题中的第一个和最后一个单词大写,而不考虑词性 在bash中有什么简单的方法可以做到这一点吗?我很感激你 (作为补充说明,这将用于parcellite操作。)$cat titles.txt 紫色烟雾 爱的人 山火 这首歌依旧 看着北风升起 八英里高 我只是顺道来的 草莓

如何在遵循规则的同时将字符串转换为标题大小写,而不仅仅是将单词的每个首字母大写

示例规则:

  • 除以下文字外,所有文字均大写:
  • 将所有冠词(a,the)、介词(to、at、in、with)和并列连词(and、but、or)小写
  • 将标题中的第一个和最后一个单词大写,而不考虑词性
在bash中有什么简单的方法可以做到这一点吗?我很感激你

(作为补充说明,这将用于
parcellite
操作。)

$cat titles.txt
紫色烟雾
爱的人
山火
这首歌依旧
看着北风升起
八英里高
我只是顺道来的
草莓信23
$cat cap.awk
开始{split(“a to at in on with and but or”,w)
对于(i in w)nocap[w[i]]}
功能帽(字){
返回toupper(substr(word,1,1))到lower(substr(word,2))
}
{

对于(i=1;i感谢@jas为这个问题提供了一个很好的答案。最终,我需要的是
parcellite
壳中的一个长内衬(为了对管道的热爱!)


感谢那些尝试过的人。:-)

通常将所有单词大写,并将所有单词大写五个字母或更长。
这两个条件中哪一个可以省略?如果您不想让问题就此结束,请编辑您的问题以澄清您的要求,发布示例输入和预期输出,并尝试解决此问题。包括带有“单词”的标题以数字开头,数字作为第一个/最后一个“单词”,包括/由标点符号分隔的单词,等等,在您的示例或您得到的解决方案中,这些单词只适用于最简单的晴天案例的子集。
$ cat titles.txt
purple haze
Somebody To Love
fire on the mountain
THE SONG REMAINS THE SAME
Watch the NorthWind rise
eight miles high
just dropped in
strawberry letter 23

$ cat cap.awk
BEGIN { split("a the to at in on with and but or", w)
        for (i in w) nocap[w[i]] }

function cap(word) {
    return toupper(substr(word,1,1)) tolower(substr(word,2))
}

{
  for (i=1; i<=NF; ++i) {
      printf "%s%s", (i==1||i==NF||!(tolower($i) in nocap)?cap($i):tolower($i)),
                     (i==NF?"\n":" ")
  }
}

$ awk -f cap.awk titles.txt
Purple Haze
Somebody to Love
Fire on the Mountain
The Song Remains the Same
Watch the Northwind Rise
Eight Miles High
Just Dropped In
Strawberry Letter 23
$ echo "the sun also rises" | awk 'BEGIN{split("a the to at in on with and but or",w); for(i in w)nocap[w[i]]}function cap(word){return toupper(substr(word,1,1)) tolower(substr(word,2))}{for(i=1;i<=NF;++i){printf "%s%s",(i==1||i==NF||!(tolower($i) in nocap)?cap($i):tolower($i)),(i==NF?"\n":" ")}}'
The Sun Also Rises
echo '%s' | sed 's/\<./\u&/g' | sed 's/\ The\ /\ the\ /' | sed 's/\ A\ /\ a\ /' | sed 's/\ An\ /\ an\ /' | sed 's/\ As\ /\ as\ /' | sed 's/\ At\ /\ at\ /' | sed 's/\ But\ /\ but\ /' | sed 's/\ By\ /\ by\ /' | sed 's/\ For\ /\ for\ /' | sed 's/\ In\ /\ in\ /' | sed 's/\ Of\ /\ of\ /' | sed 's/\ Off\ /\ off\ /' | sed 's/\ On\ /\ on\ /' | sed 's/\ Per\ /\ per\ /' | sed 's/\ To\ /\ to\ /' | sed 's/\ Up\ /\ up\ /' | sed 's/\ Via\ /\ via\ /' | sed 's/\ And\ /\ and\ /' | sed 's/\ Nor\ /\ nor\ /' | sed 's/\ Or\ /\ or\ /' | sed 's/\ So\ /\ so\ /' | sed 's/\ Yet\ /\ yet\ /' | parcellite
for word in {The,A,An,As,At,But,By,For,In,Of,Off,On,Per,To,Up,Via,And,Nor,Or,So,Yet}
do
    low=`echo "$word" | tr '[A-Z]' '[a-z]'`
    printf "sed 's/\ $word\ /\ $low\ /' | "
done