AWK合并两个文件交叉线

时间:2013-04-05 17:46:23

标签: awk playlist gawk

并感谢您花点时间阅读此内容,此时我正在尝试使用icecast完成并打磨一个小广播电台,一切都已经在运行。

然而,有一个名为ezstream的程序,它所做的只是当没有人在线时将音乐流式传输到icecast中,它是最常见的autodj,它使用播放列表。

所说的播放列表可以播放一次并且程序关闭,这正是我想在这里利用的,我设法自动创建两个不同的播放列表,一个包含所有音乐,另一个包含广告,jingles和soundbytes,以及基本上它们只是存储在计算机上的文件列表。如下所示,显然他们有名字和东西。

这将是播放列表1

/home/mp3/albums/album1/title1.mp3

/home/mp3/albums/album1/title2.mp3

/home/mp3/albums/album1/title3.mp3

/home/mp3/albums/album1/title4.mp3

/home/mp3/albums/album1/title5.mp3

/home/mp3/albums/album2/title1.mp3

/home/mp3/albums/album2/title2.mp3

/home/mp3/albums/album2/title3.mp3

/home/mp3/albums/album2/title4.mp3

/home/mp3/albums/album2/title5.mp3

播放列表2非常相似,但它只包含广告,所以它看起来像这样

/home/mp3/commercials/commercial1.mp3

/home/mp3/commercials/commercial2.mp3

/home/mp3/commercials/commercial3.mp3

/home/mp3/commercials/commercial4.mp3

/home/mp3/commercials/commercial5.mp3

我严重陷入困境的那个部分是2:1或3:1的比例(如果你能给我一个两个代码的手,它也会很棒。

最终输出应该看起来像这样

/home/mp3/albums/album1/title1.mp3

/home/mp3/albums/album1/title2.mp3

/home/mp3/commercials/commercial1.mp3

/home/mp3/albums/album1/title3.mp3

/home/mp3/albums/album1/title4.mp3

/home/mp3/commercials/commercial2.mp3

/home/mp3/albums/album1/title5.mp3

/home/mp3/albums/album2/title1.mp3

/home/mp3/commercials/commercial2.mp3

等等,直到两个文件完全合并,到目前为止我只是设法找到这个代码,但由于某些原因它不起作用,它会产生与语法相关的错误并且缺少一个<符号。

AWK代码:

awk ‘FNR==NR{

song[FNR]=$0; 
next 
}

{

print song[FNR+line];line++;

print song[FNR+line]

print $0

}’ playlist1.m3u playlist2.m3u

所有这些都应该输出到第三个文件mergedplaylists.m3u

我没有创建那个代码,虽然我已经尝试了一段时间,但是对我来说不太清楚的一件事就是为什么它会在那里说“歌曲”,是否可以为其他东西改变?说“专辑”?

代码根本不起作用,也没有在输出文件中写入内容(我也不知道它是否正确)。

我希望some1可以帮助我了解特定情况,AWK似乎很有帮助,但它非常神秘,我发现很多问题需要理解......

再次感谢你

1 个答案:

答案 0 :(得分:1)

这将在每个广告之前放两首歌曲:

awk '
FNR==NR{ song[++numSongs]=$0; next }
{
   for (i=1;i<=2;i++)
      print song[++songNr]
   print
}
songNr == numSongs { exit }
' playlist1.m3u playlist2.m3u

将“2”更改为“3”或其他任何内容。

基于以下评论的替代实施:

$ cat tst.awk
BEGIN{ interval = (interval ? interval : 3) }

NR==FNR { songs[++numSongs] = $0; next }

{ commercials[++numCommercials] = $0 }

END {
    for (songNr=1; songNr<=numSongs; songNr++) {

        print songs[songNr]

        if ( !( songNr % interval) && (++commercialNr in commercials) )
            print commercials[commercialNr]

    }

}
$
$ cat songs.txt
/home/mp3/albums/album1/title1.mp3
/home/mp3/albums/album1/title2.mp3
/home/mp3/albums/album1/title3.mp3
/home/mp3/albums/album1/title4.mp3
/home/mp3/albums/album1/title5.mp3
/home/mp3/albums/album2/title1.mp3
/home/mp3/albums/album2/title2.mp3
/home/mp3/albums/album2/title3.mp3
/home/mp3/albums/album2/title4.mp3
/home/mp3/albums/album2/title5.mp3
$
$ cat commercials.txt
/home/mp3/commercials/commercial1.mp3
/home/mp3/commercials/commercial2.mp3
/home/mp3/commercials/commercial3.mp3
/home/mp3/commercials/commercial4.mp3
/home/mp3/commercials/commercial5.mp3
$
$ awk -f tst.awk songs.txt commercials.txt
/home/mp3/albums/album1/title1.mp3
/home/mp3/albums/album1/title2.mp3
/home/mp3/albums/album1/title3.mp3
/home/mp3/commercials/commercial1.mp3
/home/mp3/albums/album1/title4.mp3
/home/mp3/albums/album1/title5.mp3
/home/mp3/albums/album2/title1.mp3
/home/mp3/commercials/commercial2.mp3
/home/mp3/albums/album2/title2.mp3
/home/mp3/albums/album2/title3.mp3
/home/mp3/albums/album2/title4.mp3
/home/mp3/commercials/commercial3.mp3
/home/mp3/albums/album2/title5.mp3
$
$ awk -v interval=1 -f tst.awk songs.txt commercials.txt
/home/mp3/albums/album1/title1.mp3
/home/mp3/commercials/commercial1.mp3
/home/mp3/albums/album1/title2.mp3
/home/mp3/commercials/commercial2.mp3
/home/mp3/albums/album1/title3.mp3
/home/mp3/commercials/commercial3.mp3
/home/mp3/albums/album1/title4.mp3
/home/mp3/commercials/commercial4.mp3
/home/mp3/albums/album1/title5.mp3
/home/mp3/commercials/commercial5.mp3
/home/mp3/albums/album2/title1.mp3
/home/mp3/albums/album2/title2.mp3
/home/mp3/albums/album2/title3.mp3
/home/mp3/albums/album2/title4.mp3
/home/mp3/albums/album2/title5.mp3
$
$ awk -v interval=2 -f tst.awk songs.txt commercials.txt
/home/mp3/albums/album1/title1.mp3
/home/mp3/albums/album1/title2.mp3
/home/mp3/commercials/commercial1.mp3
/home/mp3/albums/album1/title3.mp3
/home/mp3/albums/album1/title4.mp3
/home/mp3/commercials/commercial2.mp3
/home/mp3/albums/album1/title5.mp3
/home/mp3/albums/album2/title1.mp3
/home/mp3/commercials/commercial3.mp3
/home/mp3/albums/album2/title2.mp3
/home/mp3/albums/album2/title3.mp3
/home/mp3/commercials/commercial4.mp3
/home/mp3/albums/album2/title4.mp3
/home/mp3/albums/album2/title5.mp3
/home/mp3/commercials/commercial5.mp3
$
$ awk -v interval=4 -f tst.awk songs.txt commercials.txt
/home/mp3/albums/album1/title1.mp3
/home/mp3/albums/album1/title2.mp3
/home/mp3/albums/album1/title3.mp3
/home/mp3/albums/album1/title4.mp3
/home/mp3/commercials/commercial1.mp3
/home/mp3/albums/album1/title5.mp3
/home/mp3/albums/album2/title1.mp3
/home/mp3/albums/album2/title2.mp3
/home/mp3/albums/album2/title3.mp3
/home/mp3/commercials/commercial2.mp3
/home/mp3/albums/album2/title4.mp3
/home/mp3/albums/album2/title5.mp3

这是awk:

BEGIN{ interval = (interval ? interval : 3) }

NR==FNR { songs[++numSongs] = $0; next }

{ commercials[++numCommercials] = $0 }

END {
    for (songNr=1; songNr<=numSongs; songNr++) {

        print songs[songNr]

        if ( !(songNr % interval) && (++commercialNr <= numCommercials) )
            print commercials[commercialNr]

    }

}

这是类似C的伪代码:

void main() {

    FILE *filep;
    char *line;

    char *songs[1000];
    char *commercials[1000];

    int FNR = 0;
    int NR = 0;
    int interval = 0;
    int numSongs = 0;
    int numCommercials = 0;
    int songNr = 0;
    int commercialNr = 0;
    int argNr = 0;

    /* BEGIN */
    if (ARGV[++argNr] == "interval") {
         interval = ARGV[++argNr];
    }
    interval = (interval ? interval : 3);

    for (++argNr;argNr<=ARGC;argNr++) {
       filep = ARGV[argNr];
       FNR = 0;
       while ( fgets(line,filep) > 0 ) {
          NR++;
          FNR++;

          if (NR == FNR) { songs[++numSongs] = line; continue; }

          commercials[++numCommercials] = line;

       }
    }

    /* END */
    for (songNr=1; songNr<=numSongs; songNr++) {

        printf("%s\n",songs[songNr]);

        if ( !(songNr % interval) && (++commercialNr <= numCommercials) )
                printf("%s\n",commercials[commercialNr]);
        }

    }

    return;
}

为了便于比较,我对awk脚本所做的唯一更改是删除了“in”运算符,其中没有明确的C等价物。

希望有助于澄清awk脚本正在做什么。