【问题标题】:Removing SOME line breaks from srt/txt file从 srt/txt 文件中删除一些换行符
【发布时间】:2015-04-03 04:44:48
【问题描述】:

我有一个包含编号条目、时间码和成绩单的文本文件。我正在尝试删除成绩单中的换行符并保留其他换行符。我正在尝试使用 grep 或 awk。

文件是这样的

1
00:00:27,160 --> 00:00:29,054
有时对话不多。

2
00:00:30,100 --> 00:00:31,090
但其他时候有很多,
它被格式化成两行

3
00:00:31,500 --> 00:00:33,700
我只想在
上删除换行符 这些长行,保留所有其他格式。

4
00:00:33,805 --> 00:00:37,285
这样所有对话最终都在一个单一的
线不管那条线有多长。

输出如下所示:

1
00:00:27,160 --> 00:00:29,054
有时对话不多。

2
00:00:30,100 --> 00:00:31,090
但其他时候有很多, 它被格式化成两行

3
00:00:31,500 --> 00:00:33,700
我只想删除换行符 这些长行,保留所有其他格式。

4
00:00:33,805 --> 00:00:37,285
因此,无论该行有多长,所有对话最终都在一条线上。

感谢所有提供帮助的人

【问题讨论】:

  • 似乎您可以在数字和双换行符之间提取文本,然后从该字符串中删除换行符并将新字符串放回......只要之间总是有一个数字和双换行符条目
  • 语法错误是因为您在 awk 脚本的每一行开头添加了> 符号。不要那样做。
  • 格式错误。再次尝试您的方法,它就像一个梦一样工作。非常感谢你

标签: awk grep line-breaks


【解决方案1】:

不要依赖以任何特定字符开头(或不包含)的行 - 只需将每条记录中的第 4 行和后续行附加到该记录的第 3 行末尾即可:

$ awk '
BEGIN { RS=ORS=""; FS=OFS="\n" }
{
    print $1,$2,$3
    for (i=4;i<=NF;i++)
        printf " %s", $i
    print "\n\n"
}
' file
1
00:00:27,160 --> 00:00:29,054
Sometimes there's not much dialogue.

2
00:00:30,100 --> 00:00:31,090
But other times there is quite a bit, and it's formatted into two lines

3
00:00:31,500 --> 00:00:33,700
I want to remove the line breaks only on these long lines, leaving all other formatting.

4
00:00:33,805 --> 00:00:37,285
So that all dialogue ends up being on a single line no matter how long that line.

【讨论】:

  • +1 我同意,最好不要有任何不需要的依赖项。
  • 嘿,刚刚在一个文件上尝试了这个但没有成功......也许我做错了什么......如果你有兴趣,这是我正在测试的字幕文件,但实际上任何字幕文件都可以测试:subtitles srt file 感谢您的帮助
  • 如果您需要帮助调试它,您需要更具体地了解“没有成功”的含义。而且我不会去点击链接寻找其他输入,只需使用特定输入示例、预期输出、您运行的命令、您获得的实际输出和任何错误消息来更新您的问题。
  • 这是我运行上述脚本时得到的结果:MACPRO:~ homedirectory$ awk ' >> BEGIN { RS=ORS=""; FS=OFS="\n" } > > { > > 打印 $1,$2,$3 > > for (i=4;i > printf " %s", $i > > print "\ n\n" > > } > > ' /Users/homedirectory/Desktop/subs_test.srt >/Users/homedirectory/Desktop/subs_test.srt awk:源代码第 2 行上下文的语法错误是 >>> >
  • 现在已经这样做了——这是我第一次使用堆栈交换,很抱歉练习不佳。谢谢你的帮助。
【解决方案2】:

我认为你需要类似的东西

awk '/[0-9]+/,/^$/{ if(NR<3) print $0; else {while($0!=""){ printf $0;next; }}}' file

它不起作用,但你可能会明白。

【讨论】:

  • 谢谢。我仍然在理解 grep/awk/perl/regex,但我会看看我是否能弄清楚这里发生了什么——这似乎很有希望。
  • 如果你想从范围开始的第一次出现到范围结束的最后一次出现(即不是我们在这里需要的),只使用像/[0-9]+/,/^$/这样的范围表达式.否则,如果没有完全重写,它们会使简单的任务稍微简单一些,但即使是稍微复杂的任务也非常困难。
【解决方案3】:

你可以用awk试试这样的东西:

awk '!NF{print}/[a-z]/{printf "%s ", $0;next}1' file

$ cat file
1
00:00:27,160 --> 00:00:29,054
Sometimes there's not much dialogue.

2
00:00:30,100 --> 00:00:31,090
But other times there is quite a bit,
and it's formatted into two lines

3
00:00:31,500 --> 00:00:33,700
I want to remove the line breaks only on
these long lines, leaving all other formatting.

4
00:00:33,805 --> 00:00:37,285
So that all dialogue ends up being on a single
line no matter how long that line.

$ awk '!NF{print}/[a-z]/{printf "%s ", $0;next}1' file
1
00:00:27,160 --> 00:00:29,054
Sometimes there's not much dialogue.

2
00:00:30,100 --> 00:00:31,090
But other times there is quite a bit,  and it's formatted into two lines

3
00:00:31,500 --> 00:00:33,700
I want to remove the line breaks only on these long lines, leaving all other formatting.

4
00:00:33,805 --> 00:00:37,285
So that all dialogue ends up being on a single line no matter how long that line.

【讨论】:

  • 再次感谢。刚刚注意到这对于提供的示例非常有效,但是当应用于 .srt 字幕文件(格式与示例相同)时,每个对话行的第一个字母都会丢失..?!我要调查一下...以防万一您立即知道发生了什么,我想我会通过您...
  • @user5268 您是否从 Windows 导入了此文件?看起来您的文件有 ^M 字符。对您的 srt 文件执行 dos2unix 并运行命令。 dos2unix 将删除那些 ^M 字符。
  • 我不会这样做,因为如果任何记录的第 4 行以 I 或任何其他大写字母(例如名称)或数字或标点符号开头,或者如果第三行以小写字母开头。
  • @EdMorton 是的,但我没有锚定正则表达式。假设只要它有一些文本,它就应该被拉起。但是话虽如此,我同意,您的解决方案要好得多。
  • 啊,我明白了,那还不错,它只会在不包含小写字母(或某些大写字母,取决于语言环境)的行上失败,这不会出现在OP 示例输入,所以可能没问题。
【解决方案4】:

删除所有以字母、空格或制表符开头的新行:

perl -pe 's/([a-zA-Z \t])\n$/$1/'

【讨论】:

  • 我认为这种方法可行,谢谢。它将两行对话合并为一条长长的对话——完美!但它似乎也摆脱了其他换行符 - 我理想情况下正在寻找一种方法来保持所有这些都完好无损,例如保留空白行等...
  • 不怕。从逻辑上讲,它应该可以完美地工作:只删除前面有一个字母的换行符正是我所追求的......谢谢顺便说一句
  • 我已经调整了我的答案,以便在行尾留出一些空白。这有帮助吗?
【解决方案5】:

我遇到了同样的问题,写了这个小代码,解决了我的问题:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(int argc, char *argv[]) {
FILE *quelle,*ziel;
int i;
long maxsub,count,tmp,sub;  
char puffer[10][200], *ptr,line[400];

if(argc != 3)
    {
    printf("Usage: srtlinejoin Filename CountOfSubtitles\n");
    return EXIT_FAILURE;
    }   

maxsub = strtol( argv[2], &ptr, 10);

if( (quelle=fopen(argv[1],"r")) == NULL) {
        fprintf(stderr, "Can't open %s\n", argv[1]);
        return EXIT_FAILURE;
    }
if( (ziel=fopen("out.srt","w")) == NULL) {
        fprintf(stderr, "Can't open out.srt\n");
    fclose(quelle);
        return EXIT_FAILURE;
    }

//read and write first line
fgets(puffer[0], 200, quelle);
fputs(puffer[0], ziel);

for(count=1; count < maxsub;count++)
//for(count=1; count <= 3;count++)
    {
    //printf("Processing subtitle %d\n",count);

    tmp=0;
    //Read and write time
    fgets(puffer[0], 200, quelle);
    fputs(puffer[0], ziel);

    do  {
        fgets(puffer[tmp], 200, quelle);
        //Scan for next Subtitle
        sub = strtol( puffer[tmp], &ptr, 10);
        tmp++;
        }
    while(sub != (count+1));

    //Der Untertitel hat nur eine Zeile
    if (strlen(puffer[1]) == 2)
        {
        fputs(puffer[0], ziel);     //New Subtitle
        fputs(puffer[1], ziel);     //Next empty line
        fputs(puffer[2], ziel);     //Next number
        }

    //Der Untertitel hat zwei Zeile
    if ((strlen(puffer[1]) > 2) && (strlen(puffer[2]) == 2))
        {
        for(i=0;i<400;i++)
            line[i]=0;

        strncpy(line,puffer[0],(strlen(puffer[0])-2));
        strcat(line," ");
        strcat(line,puffer[1]);
        fputs(line, ziel);      //New Subtitle
        fputs(puffer[2], ziel); //Next empty line
        fputs(puffer[3], ziel); //Next number
        }

    //Der Untertitel hat mehr als zwei Zeile
    if ((strlen(puffer[1]) == 2) && (strlen(puffer[2]) == 2))
        {
        printf("Attention: The subtitles has more than two lines\n");
        }
    }

printf("Check last subtitle!\n");

fclose(quelle);
fclose(ziel);
return EXIT_SUCCESS;
}

【讨论】:

    猜你喜欢
    • 2014-10-30
    • 2012-04-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多