awk - 将排除数组添加到现有 awk 代码
问题描述
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
此代码在匹配某些文本时正确地将文件的行大写,在本例中为TITLE
. 这个想法是使用它来修改一些提示表文件并按照三个基本规则正确地将它们大写:
- 将所有单词大写,但以下情况除外:
- 小写所有冠词 (a, the)、介词 (to, at, in, with) 和并列连词 (and, but, or)
- 无论词性如何,标题中的第一个和最后一个单词都大写
好吧,我想修改 awk 代码,添加第二个数组,其中包含要排除的单词列表,并始终将它们写入矩阵中。
这对于诸如 McCartney、feat.、vs.、CD、USA、NYC 等词非常有用。因为如果没有此排除数组,它们将更改为:Mccartney、Feat.、Cd、Usa、Nyc 等. 即使这些词是 TITLE 的第一个词和最后一个词,也应该排除这种情况,如相关问题中所述。
例如,对于这样的数组:"McCartney feat. vs. CD USA NYC"
代码必须将其转换为:
FILE "Two The Beatles Songs.wav" WAVE
TRACK 01 AUDIO
TITLE "dig A pony, Feat. paul mccartney"
PERFORMER "The Beatles"
INDEX 01 00:00:00
TRACK 02 AUDIO
TITLE "From Me to You"
PERFORMER "The Beatles"
INDEX 01 03:58:02
进入这个:
FILE "Two The Beatles Songs.wav" WAVE
TRACK 01 AUDIO
TITLE "Dig a Pony, feat. Paul McCartney"
PERFORMER "The Beatles"
INDEX 01 00:00:00
TRACK 02 AUDIO
TITLE "From Me to You"
PERFORMER "The Beatles"
INDEX 01 03:58:02
而不是这样做:
FILE "Two The Beatles Songs.wav" WAVE
TRACK 01 AUDIO
TITLE "Dig a Pony, Feat. Paul Mccartney"
PERFORMER "The Beatles"
INDEX 01 00:00:00
TRACK 02 AUDIO
TITLE "From Me to You"
PERFORMER "The Beatles"
INDEX 01 03:58:02
谢谢你。
解决方案
编辑: OP告诉可能有类似的词,"a"
所以现在处理这个案例添加以下内容。
awk '
BEGIN{
s1="\""
num=split("McCartney feat. vs. CD USA NYC",array," ")
for(k=1;k<=num;k++){
temp=tolower(array[k])
ignoreLetters[temp]=array[k]
}
num=split("a the to at in on with and but or",array," ")
for(i=1;i<=num;i++){
smallLetters[array[i]]=array[i]
}
}
/TITLE/{
for(i=2;i<=NF;i++){
front=end=nothing=both=""
if($i~/^"/ && $i!~/"$/){
temp=tolower(substr($i,2))
front=1
}
else if($i ~ /^".*"$/){
temp=tolower(substr($i,2,length($i)-2))
both=1
}
else if($i ~/"$/ && $i!~/^"/){
temp=tolower(substr($i,1,length($i)-1))
end=1
}
else{
temp=tolower($i)
nothing=1
}
if(temp in ignoreLetters){
if(front){
$i=s1 ignoreLetters[temp]
}
else if(end){
$i=ignoreLetters[temp] s1
}
else if(both){
$i=s1 ignoreLetters[temp] s1
}
else if(nothing){
$i=ignoreLetters[temp]
}
}
else if(temp in smallLetters){
if(front){
$i=s1 smallLetters[temp]
}
else if(end){
$i=smallLetters[temp] s1
}
else if(nothing){
$i=smallLetters[temp]
}
else if(both){
$i=s1 smallLetters[temp] s1
}
}
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
请您尝试以下操作。
awk '
BEGIN{
s1="\""
num=split("McCartney feat. vs. CD USA NYC",array," ")
for(k=1;k<=num;k++){
temp=tolower(array[k])
ignoreLetters[temp]=array[k]
}
num=split("a the to at in on with and but or",array," ")
for(i=1;i<=num;i++){
smallLetters[array[i]]=array[i]
}
}
/TITLE/{
for(i=2;i<=NF;i++){
front=end=nothing=""
if($i~/^"/){
temp=tolower(substr($i,2))
front=1
}
else if($i ~/"$/){
temp=tolower(substr($i,1,length($i)-1))
end=1
}
else{
temp=tolower($i)
nothing=1
}
if(temp in ignoreLetters){
if(front){
$i=s1 ignoreLetters[temp]
}
else if(end){
$i=ignoreLetters[temp] s1
}
else if(nothing){
$i=ignoreLetters[temp]
}
}
else 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
输出如下:
FILE "Two The Beatles Songs.wav" WAVE
TRACK 01 AUDIO
TITLE "Dig a Pony, feat. Paul McCartney"
PERFORMER "The Beatles"
INDEX 01 00:00:00
TRACK 02 AUDIO
TITLE "From Me to You"
PERFORMER "The Beatles"
INDEX 01 03:58:02
代码负责什么:
- 它负责将提到的单词变成小写字母。
- 它负责根据他们的风格制作一些字母,由 OP 提到。
- 它取其余不属于上述任何类别的字段,并将其首字母设为大写字母。
"
代码也会处理以OR开头的单词"
,它会首先删除它们以检查它们是否存在于用户提到的数组中,然后根据它们的位置添加它们。