Sed
當存在多行時,如何從另一個文件中刪除文本文件中的佔位符?
我有一個文件:
- id: 1.4.25.2 name: 'Configuring a VNC Server' permalink: '/rhcsa/managing-network-services/configuring-vnc-access/configuring-a-vnc-server' description: '<*description>' content: [] - id: 1.4.25.3 name: 'Connecting to a VNC Server' permalink: '/rhcsa/managing-network-services/configuring-vnc-access/connecting-to-a-vnc-server' description: '<*description>' content: []
我必須
<*description>
用一些文本替換每個。顯然,我想到了使用正則表達式。顯然(根據本網站上的某些答案),sed
沒有用於替換的非貪婪修飾符。因此,我嘗試使用 perl:(.*id: 1\.4\.25\.2(?:\n|.)*)\'(\<\*description\>)\'
不會選擇所需的部分,即 from
- id: 1.4.25.2
untildescription: '<*description>'\ncontent: []
,就在 yaml 數組中的下一個元素之前,即 line 之前- id: 1.4.25.3
。我想不出一種方法來做到這一點,以及如何使用從其他地方提取的自定義文本來更改文件中每個條目的描述!
使用 YAML 模組;遞歸遍歷資料結構並將此處的任何匹配元素替換為在標準輸入中讀取的行。
#!/usr/bin/env perl use strict; use warnings; use Data::Dumper; use YAML::Tiny; my $yaml = YAML::Tiny->read( $ARGV[0] // die "Usage: $0 yaml-file [out-file]\n" ); mangle_description( $yaml->[0] ); $yaml->write( $ARGV[1] // "$ARGV[0].out" ); sub mangle_description { my $what = shift; my $type = ref $what; if ( $type eq 'HASH' ) { for my $key ( keys %$what ) { if ( $key eq 'description' and $what->{$key} eq '<*description>' ) { $what->{$key} = set_description(); } mangle_description( $what->{$key} ) if ref $what->{$key}; } } elsif ( $type eq 'ARRAY' ) { for my $entry (@$what) { mangle_description($entry); } } else { warn Dumper $what; die "unknown type in YAML ??\n"; } } sub set_description { my $next = readline *STDIN; chomp $next; return $next; }
以上保存為
parser
有效 YAML 並保存在input
:$ yes | perl parser input $ grep description input.out description: y description: y $