Ответ 1
Это может сработать для вас:
csplit -z -f 'temp' -b '%02d.txt' file /Rate/ {*}
Это создаст файлы temp00.txt, temp01.txt...
Если вам нужна только строка Rate
,
sed -i '/Rate/!d' temp*.txt
Мне нужна ваша помощь в создании файла txt с помощью bash/linux. Файл выглядит следующим образом: в нем всегда есть строка Rate: Sth, затем она следует с деталями в очень специфическом формате. Я хотел бы разделить файл с одной ставкой для каждого файла. В этом примере я хотел бы иметь 3 файла, и каждый из них имеет соответствующую строку, в которой указано значение Rate.
Как вы подходите к этому?
line No. Main Text
1 Rate: GBP
2 12/01/1999,90.5911501,Validated
.....
.....
210 18/01/1999,90.954996,Validated
211 Rate: RMB
212 24/04/2008,132.2542,Validated
.....
1000 25/04/2008,132.2279,Validated
1001 28/04/2008,131.69915,Validated
1002 Rate: USD
1003 21/11/11,-0.004419534,Validated
Это может сработать для вас:
csplit -z -f 'temp' -b '%02d.txt' file /Rate/ {*}
Это создаст файлы temp00.txt, temp01.txt...
Если вам нужна только строка Rate
,
sed -i '/Rate/!d' temp*.txt
Я сделал бы это в perl:
#!/usr/bin/perl
use strict;
use warnings;
open (my $out, ">-") or die "oops";
while(<>)
{
if (m/^Rate: (\w+)/o)
{
close $out and open ($out, ">$1") or die "oops";
next;
}
print $out $_
}
Используйте его как
perl ./test.pl input.txt
(g)awk
на помощь:
awk '/^Rate:/ {output_file_name=$2; getline }
{ print $0 >> ( output_file_name ) }' INPUT_FILE
Первое правило и команда выполняется для строк, начинающихся с Rate:
, и только устанавливает имя выходного файла, затем получает следующую строку из входного файла. Затем эта следующая строка обрабатывается и записывается в выходной файл. После этого следующая строка обрабатывается только второй командой (записывается в выходной файл), но только если она не соответствует Rate:
.
ПРИМЕЧАНИЕ. Вышеупомянутое решение может выйти из строя, если во входном файле есть раздел с двумя непрерывными строками Rate:
s, например:
... DATA ...
Rate: GBP
Rate: CHF
... DATA ...
должен (предположим, что номера строк не являются частью исходного файла).
НТН
Один лайнер, вдохновленный ответом:
>perl -pwe '
> if (/^Rate: (.+)/) {
> open $out, ">", "Rate_$1.txt" or die $!;
> select $out;
> }' gasdata.txt
Опция -p
будет читать строку и печатать ее после того, как будет оценен код в -e
. select
выберет дескриптор файла по умолчанию для print
. Итак, в основном, то, что мы делаем, это просто манипулирование файловым дескриптором вокруг, в зависимости от того, какая скорость в настоящий момент активна.
Здесь код депарафинирован:
>perl -MO=Deparse -pwe 'if (/^Rate: (.+)/) { open $out, ">", "output/Rate_$1.txt" or die $!; select $out; }' gasdata.txt
BEGIN { $^W = 1; }
LINE: while (defined($_ = <ARGV>)) {
if (/^Rate: (.+)/) {
die $! unless open $out, '>', "output/Rate_$1.txt";
select $out;
}
}
continue {
die "-p destination: $!\n" unless print $_;
}
-e syntax OK
Другое решение: он просто делает ваш входной файл в script, а затем запускает его:
sed 's/^Rate:/cat <<EOF >/; 1!s/^cat <<EOF/EOF\n&/; $aEOF' input.txt | bash
Я предположил, что номера строк - это не часть файла.
Вы можете использовать что-то вроде этого в perl -
Perl Script:
#!/usr/bin/perl
undef $/;
$_ = <>;
$n = 0;
for $match (split(/(?=Rate)/)) {
open(O, '>temp' . ++$n);
print O $match;
close(O);
}
Исполнение:
[jaypal~/temp]$ ./spl.pl temp.file
[jaypal~/temp]$ **cat temp.file**
Line No. Main Text
1 Rate: GBP
2 12/01/1999,90.5911501,Validated
.....
.....
210 18/01/1999,90.954996,Validated
211 Rate: RMB
212 24/04/2008,132.2542,Validated
.....
1000 25/04/2008,132.2279,Validated
1001 28/04/2008,131.69915,Validated
1002 Rate: USD
1003 21/11/11,-0.004419534,Validated
[jaypal~/temp]$ cat temp1
Line No. Main Text
1
[jaypal~/temp]$ cat temp2
Rate: GBP
2 12/01/1999,90.5911501,Validated
.....
.....
210 18/01/1999,90.954996,Validated
211
[jaypal~/temp]$ cat temp3
Rate: RMB
212 24/04/2008,132.2542,Validated
.....
1000 25/04/2008,132.2279,Validated
1001 28/04/2008,131.69915,Validated
1002 [jaypal~/temp]$ cat temp4
Rate: USD
1003 21/11/11,-0.004419534,Validated
[jaypal~/temp]$