Мне нужна помощь в извлечении блоков информации из одного текстового файла в новые файлы или в какую-либо форму, где я могу манипулировать данными из каждого блока.

Примере:

[Block1]
this=that
here=there
why=why_not

[Block2]
this=those
here=there
why=because

Мне нужно иметь возможность отображать и / или манипулировать переменными (что я могу сделать, если смогу выделить правильную). Я не против записи каждого из этих блоков во временный файл

Итак, как бы я изменил here=there на here=anywhere только в Block2?

Я пытался понять это, используя sed / awk, но безрезультатно.

1
Chip 2 Сен 2017 в 01:12

5 ответов

Лучший ответ

Возможное решение с использованием Perl:

perl -00 -pe '/^\[Block2\]\n/ or next; s/^here=there$/here=anywhere/m'

-p говорит Perl обернуть код в неявный цикл ввода / вывода (аналогично sed).

-00 говорит Perl обрабатывать ввод в единицах абзацев (вместо строк).

-e ... определяет программу. Сначала убедитесь, что абзац начинается с [Block2] (в противном случае мы пропускаем всю другую обработку). Затем мы заменяем строку вида here=there на here=anywhere.

0
melpomene 1 Сен 2017 в 22:28

Это разделит файл для вас на файлы с именами block1, block2 и т. Д. И внесет необходимые изменения в Block2, и он будет работать с любым awk на любом компьютере UNIX:

awk -v RS= -F'\n' '
{
    close(out)
    out = "block" NR
    if ($1 == "[Block2]") {
        sub(/here=there/,"here=anywhere")
    }
    print > out
}
' file

С GNU awk это даже короче:

awk -vRS= -F'\n' '$1=="[Block2]"{sub(/here=there/,"here=anywhere")} {print>("block"NR)}' file
1
Ed Morton 2 Сен 2017 в 13:51

С помощью sed:

sed '/^\[Block2\]/,/^$/s/here=there/here=anywhere/' file
  • /^\[Block2\]/,/^$/: между строкой, начинающейся с [Block2], до следующей пустой строки (^$) или концом файла ...
  • s/here=there/here=anywhere/: заменить here=there на here=anywhere
4
SLePort 2 Сен 2017 в 07:44

Я бы использовал Config :: IniFiles Модуль Perl. Если вы работаете в системе RedHat или Centos, попробуйте это:

$ sudo yum install perl-Config-IniFiles

Для Ubuntu используйте apt-get ....

Вот модифицированная версия примера сценария из резюме Config :: IniFile:

$ cat syn.pl
#!/bin/perl -w

use strict;

use Config::IniFiles;
my $cfg = Config::IniFiles->new( -file => "./inifile.ini" );
print "The value is " . $cfg->val( 'Block2', 'here' ) . ".\n"
    if $cfg->val( 'Block2', 'here' );

Вот пример запуска:

$ cat inifile.ini
[Block1]
this=that
here=there
why=why_not

[Block2]
this=those
here=there
why=because
$ ./syn.pl
The value is there.

Изменить here в Block2 очень просто:

$ cat rewrite.pl
#!/bin/perl -w

use strict;

use Config::IniFiles;
my $cfg = Config::IniFiles->new( -file => "./inifile.ini" );
print "The value is " . $cfg->val( 'Block2', 'here' ) . ".\n"
    if $cfg->val( 'Block2', 'here' );
$cfg->setval( 'Block2', 'here', 'anywhere' );
$cfg->RewriteConfig();
$ cat inifile.ini
[Block1]
this=that
here=there
why=why_not

[Block2]
this=those
here=there
why=because
$ ./rewrite.pl
The value is there.
$ cat inifile.ini
[Block1]
this=that
here=there
why=why_not

[Block2]
this=those
here=anywhere
why=because
0
Red Cricket 2 Сен 2017 в 08:33

Сначала вставьте «здесь = везде», а затем удалите дублет.

awk '/this=those/{print;print "here=anywhere";next}!($0 in a) {a[$0];print}' file

[Block1]
this=that
here=there
why=why_not

[Block2]
this=those
here=anywhere
why=because
0
Claes Wikner 4 Сен 2017 в 14:52