我如何获得"awk"修改文件的某些行,而不是整个文件? [英] How do I get "awk" to modify only certain lines of a file, instead of the whole file?
问题描述
I would like to reuse this awk code, to properly capitalice some cue sheet audio files. This code not only capitalice all the words, but follows some capitalization rules, as explained in the linked question.
问题在于如何修改此代码以仅大写"
The problem is how to modify this code to capitalize only the "TITLE" lines, and not the whole file. For example, with this simple cue sheet:
FILE "Two The Beatles Songs.wav" WAVE
TRACK 01 AUDIO
TITLE "dig A pony"
PERFORMER "The Beatles"
INDEX 01 00:00:00
TRACK 02 AUDIO
TITLE "from me to you"
PERFORMER "The Beatles"
INDEX 01 03:58:02
并带有一个简单的for循环和awk代码,例如:
And with a simple for loop plus the awk code, for example something like this:
#!/bin/sh
for cue_file in *.cue
do
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":" ")}}' "$cue_file" > ~/temp_cue_file && mv ~/temp_cue_file "$cue_file"
done
运行脚本后的结果必须是:
The result after running the script must be:
FILE "Two The Beatles Songs.wav" WAVE
TRACK 01 AUDIO
TITLE "Dig a Pony"
PERFORMER "The Beatles"
INDEX 01 00:00:00
TRACK 02 AUDIO
TITLE "From Me to You"
PERFORMER "The Beatles"
INDEX 01 03:58:02
也就是说,用 TITLE挖小马"
代替 TITLE挖小马"
.和 TITLE从我到你"
而不是 TITLE从我到你"
.
That is, TITLE "Dig a Pony"
instead of TITLE "dig A pony"
. And TITLE "From Me to You"
instead of TITLE "from me to you"
.
请求是:
- 如前所述,shell脚本必须
仅更改TITLE行(全部更改),而其余部分不更改. - shell脚本必须在POSIX sh shell下运行.就我而言,是FreeBSD.
- 一行awk代码将不胜感激.
- As explained before, the shell script must change only the TITLE lines (all of them), and not the rest.
- The shell script must run under a POSIX sh shell. In my case, FreeBSD.
- An one line awk code would be appreciated.
To follow the same "capitalize rules" as the linked question (and that the provided awk follows). That is:
- 除以下以外的所有单词均大写:
- 将所有文章(a,the),介词(到,在,在,在,与)和协调连词(和,但是,或)小写
- 将标题中的第一个和最后一个单词大写,而不考虑词性的不同
如何修改awk代码以获得此结果?
How can the awk code be adapted to obtain this result?
谢谢.
上一行的awk代码在链接的答案中显示为展开:
The previous one line awk code, appears expanded in the linked answer:
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":" ")
}
}
推荐答案
能否请您尝试以下操作.
Could you please try following.
awk '
BEGIN{
num=split("a the to at in on with and but or",array," ")
for(i=1;i<=num;i++){
smallLetters[array[i]]
}
}
/TITLE/{
for(i=2;i<=NF;i++){
if(tolower($i) in smallLetters){
$i=tolower(substr($i,1,1)) substr($i,2)
}
else{
if($i~/^\"/){
$i=substr($i,1,1) toupper(substr($i,2,1)) substr($i,3)
}
else{
$i=toupper(substr($i,1,1)) substr($i,2)
}
}
}
}
1
' Input_file
说明: :添加了上述代码的详细说明.
Explanation: Adding detailed explanation for above code.
awk ' ##Starting awk program from here.
BEGIN{ ##Starting BEGIN section of this program from here.
num=split("a the to at in on with and but or",array," ") ##Creating array for all words needs to be of lower size.
for(i=1;i<=num;i++){ ##Running a for loop from i=1 to tillvalue of num(length of array).
smallLetters[array[i]] ##Creating an array named smallLetters with index of variable i here.
}
}
/TITLE/{ ##Checking condition if a line contains string TITLE then do following.
for(i=2;i<=NF;i++){ ##Running a for loop from 2nd field to last field of line.
if(tolower($i) in smallLetters){ ##Checking condition if lower case current field is present in array smallLetters.
$i=tolower(substr($i,1,1)) substr($i,2) ##Changing current field to lower case for 1st letter and keeping rest same as it is.
}
else{ ##If current field is NOT in array then do following.
if($i~/^\"/){ ##Checking if field starts from " then do following.
$i=substr($i,1,1) toupper(substr($i,2,1)) substr($i,3) ##Only make 2nd letter Capital since 1st is "
}
else{
$i=toupper(substr($i,1,1)) substr($i,2) ##Else make1st character capital and keep as it is.
}
}
}
}
1 ##Printing edited/non-edited lines here.
' Input_file ##Mentioning Input_file name here.
这篇关于我如何获得"awk"修改文件的某些行,而不是整个文件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!