2013-02-07 191 views
1

我想使用sed或类似的东西在文本文件中读取,并将大写短语的所有实例更改为用\ textsc {* *}包装的小写。如何改变这种情况下的情况?

如:

THIS SENTENCE IS ALL CAPS except not really 

应该成为

\textsc{this sentence is all caps} except not really 

如果

This Sentence Has Many Caps 

应该保持

This Sentence Has Many Caps 

与此模式s/\(.[A-Z]*\)/textsc{\L\1}/,字符串只是改变第一个字。

任何人都可以指给我一个正确的方法吗?

更新:正则表达式模式应该涵盖撇号以及

I'll BUY YOU A DRINK 

大部分的解决方案打破信这样\textsc{i}'ll \textsc{buy you a} \textsc{drink}

回答

2

这看起来应该适合你。

echo "THIS sentence IS ALL CAPS Except not really BUT THIS IS" | \ 
    sed -re "s/\b(([A-Z]+ [A-Z]+)+)\b/\\\textsc{\L\1}/g" 

这导致了这个短语:

THIS sentence \textsc{is all caps} Except not really \textsc{but this is} 

/g是一个全球性的更换(不只是第一场比赛)。 \b表示一个短语必须以单词边界开始和结束(不在单词的中间)。在textsc之前的三个斜杠是逃生(逃生)以产生最终的\textsc([A-Z]+ [A-Z]+)+是捕获一个全部大写的短语。我首先尝试在字符类中添加一个空格,如[A-Z ],但这会在花括号之前形成一个空格,如\text{this sentence }。所以我把这个空间建立在单词的中间来创建一个短语。

请注意,这只留下孤立的大写单词。因为问题是关于“短语”的,所以我认为这是有意的。但是,如果你需要,以取代那些为好,试试这个:

echo "THIS sentence IS ALL CAPS Except not really BUT THIS IS" | \ 
    sed -re "s/\b((([A-Z]+ [A-Z]+)+)|[A-Z]+)\b/\\\textsc{\L\1}/g" 

导致

\textsc{this} sentence \textsc{is all caps} Except not really \textsc{but this is} 
+0

对于第一个脚本来说看起来很不错,但是它在“这个句子有很多上限”的情况下失败了,输出是'“\ textsc {这个句子h}如同许多上限' –

+0

Upda我的答案是处理这个案件。将\ b添加到正则表达式中 –

3
$ cat file 
THIS SENTENCE IS ALL CAPS except not really 
This Sentence Has Many Caps 
THIS SENTENCE Has Many Caps 

$ awk -f tst.awk file 
\textsc{this sentence is all caps} except not really 
This Sentence Has Many Caps 
\textsc{this sentence} Has Many Caps 

$ cat tst.awk 
{ 
    while (match($0, /([[:upper:]]{2,}[[:space:]]*)+/)) { 
     rstart = RSTART 
     rlength = RLENGTH 

     if (match(substr($0,RSTART,RLENGTH), /[[:space:]]+$/)) { 
     rlength = rlength - RLENGTH 
     } 

     $0 = substr($0,1,rstart-1) \ 
      "\\textsc{" tolower(substr($0,rstart,rlength)) "}" \ 
      substr($0,rstart+rlength) 
    } 

    print 
} 
1

这可能为你工作(GNU SED):

sed -r 's/\b[A-Z]+\b(*\b[A-Z]+\b)*/\\textsc{\L&}/g' file