如何在UNIX中分解这样的文件?

时间:2015-02-19 23:35:03

标签: unix file-manipulation

我有一个主文件,其中包含3696个文件的内容。每个文件都有一个重复的结构:它以包含引号中的文件名的行开头,以.结尾。文件中没有其他重复。有没有办法将主文件分解为这些较小的文件? 例如,如果主文件包含两个文件,如下所示,

    "features/mmjr0_si2166.rec"
0 1800000 L104 -755.825928
1800000 2600000 L25 -397.663269
2600000 3600000 L6 -419.864960
3600000 3800000 L98 -116.326584
3800000 4500000 L104 -315.009827
4500000 5500000 L93 -447.467133
5500000 6300000 L12 -352.010101
6300000 7600000 L45 -556.794006
7600000 7900000 L8 -175.087677
.
"features/mesd0_si1002.rec"
0 1300000 L104 -530.985107
1300000 1700000 L13 -207.014145
1700000 2300000 L47 -303.084534
2300000 2900000 L104 -300.312927
2900000 3200000 L96 -151.823212
3200000 3700000 L46 -235.867447
3700000 4000000 L49 -170.302170
4000000 5200000 L97 -517.739868
5200000 6200000 L28 -453.094452
.

我希望它们分开,并且都存储在目录“features”中,名为mmjr0_si2166.rec的第一个文件和第二个文件mesd0_si1002.rec

2 个答案:

答案 0 :(得分:1)

在Perl中编写它可能有更简洁的方法,但这有第一次工作的优点:

#!/usr/bin/env perl
use strict;
use warnings;

my $fh = undef;

while (<>)
{
        if (/^\s*"([^"]+)"\s*$/)
        {
                my $new_file = $1;
                close $fh if (defined $fh);
                open $fh, ">", $new_file or die "Failed to open $new_file";
        }
        elsif (/^\s*\.\s*$/)
        {
                # Ignore lines with a dot only
                next;
        }
        else
        {
                print $fh $_;
        }
}

它会从生成的文件中省略文件名和点标记。包含它们所需的变化是微不足道的。如果遇到“点线”,它就不会反对。后面没有文件名行。它假定文件的目录(或目录)已存在。如果这是一个问题,您可以在打开文件之前使用模块创建目录。它允许在文件名周围的引号之前和之后使用空格;它还允许它们在包含一个点的行之前和之后。如果这不合适,你可以调整正则表达式。

答案 1 :(得分:1)

awk示例

#!/bin/bash
if [ ! -d features ] 
then
       mkdir features
fi
tr -d '"' < bigfile |
  awk '/features/ { close(file); file=$1; next}
            {print $0 >file} '