首页 > 解决方案 > 在标记之间改组文件的某些部分

问题描述

我有看起来像这样的文件:

asdasadsdasdas
dasdasdasdasd
asdas
dasd
asdas
das
das
das
das
das
#SHUFFLE_MARK_START
das
d
das
das
dasd
asd
asdas
das
das
afs
sf
#SHUFFLE_MARK_END
fas
fas
fas
fas
fas
fas
fas
fas

我只想在两个标记之间随机播放文件的一部分 -#SHUFFLE_MARK_START并且#SHUFFLE_MARK_END,随机播放标记可以是我想要的任何字符串,它们只需要在文件方面是唯一的,有什么想法如何在 bash 中做到这一点,所以它很有效?

我已经尝试通过做类似的事情来做到这一点

cat file | grep -P '.+#SHUFFLE_MARK_START' > start
cat file | grep -P '#SHUFFLE_MARK_START.+#SHUFFLE_MARK_FINISH' | shuff | > middle
cat file | grep -P '#SHUFFLE_MARK_FINISH.+' > end
echo start middle end > shuffled

但是对于大文件来说它很慢,上面的命令可能有点错误,因为我从内存中输入它们只是为了展示想法

标签: bashawkshuffle

解决方案


这是一个执行此操作的 perl 脚本:

#!/usr/bin/perl
# Usage: foo.pl input.txt > output.txt
# or
# foo.pl < input.txt > output.txt
use warnings;
use strict;
use List::Util qw/shuffle/;
my $in_block = 0;
my @lines;
while (<>) {
  if (/#SHUFFLE_MARK_START/) {
    print;
    $in_block = 1;
  } elsif (/#SHUFFLE_MARK_END/) {
    print shuffle(@lines);
    print;
    $in_block = 0;
    @lines = ();
  } elsif ($in_block == 0) {
    print;
  } else {
    push @lines, $_;
  }
}

(如果您不想包含 #SHUFFLE_MARK_START 等行,请删除相应的print;行)


推荐阅读