ファイルにこのようなものがあります。 1、2、4の行番号のリストがあります。
- すべてのニーズを満たすライン番号
- 間のコンテンツの抽出最初の出現と最後起こった
</book>
データ:
</p><p>abc</p></book><book><p style="text-indent:0em;">def</p></book><book><p>ghi</p><p style="text-indent:0em;"></book><book><div><p>
</div><p>123</p></book><book><p style="text-indent:0em;">456</p><p>789</p><p style="text-indent:0em;"></book><book><div><p>
<div><p>nothing !!!</p></div>
</p><p>ABC</p></book><book><p style="text-indent:0em;">DEF</p></book><book><p>GHI</p><p style="text-indent:0em;"></book><book><div><p>JKL</p></div></book><div>
行番号を入力してください:1、2、4(コマンドに入力したいもの)
希望の出力:
<book><p style="text-indent:0em;">def</p></book><book><p>ghi</p><p style="text-indent:0em;"></book>
<book><p style="text-indent:0em;">456</p><p>789</p><p style="text-indent:0em;"></book>
<book><p style="text-indent:0em;">DEF</p></book><book><p>GHI</p><p style="text-indent:0em;"></book><book><div><p>JKL</p></div></book>
答え1
1) 特定の行の抽出
4行目の例では、3行目を削除して1行目、2行目、4行目を簡単に抽出できます。
sed 3d file
ただし、ファイルがより複雑になる可能性があるため、より一般的な解決策は次のとおりです。
sed -e 1b -e 2b -e 4b -e d file
したがって、保持する必要がある各行に対してスクリプトの最後に移動して、残りのb
ファイルを削除できます。
より長い行番号のリストについては、スクリプトを生成する必要があるかもしれません。
sed $(for i in 1 2 4; do echo "-e ${i}b"; done) -e d file
ところで、問題は行番号ではなく、行に<book>
sがあるかどうかのようです。これが本当なら、行番号を忘れて、次のことをお勧めします。
sed '/<book>/!d'
2) コンテンツ抽出
正規表現は*
この種の操作には適していません。これが私の個人的なバージョンに一致する部分だけを置き換えるsed
コマンドオプションがある理由です。o
s
o
sed '/<book>/!d;s_<book>.*</book>_&_o'
しかし、それはあなたには効果がないので、より正規表現のジャグリングが必要です。
sed '/<book>/!d;s_<book>_\n&_;s_.*\n__;s_\(.*</book>\).*_\1_' file
sed
あなたのバージョンが代替文字列をサポートしていない場合は、\n
実際の改行文字を使用してください(バックスラッシュでエスケープされます)。
sed '/<book>/!d;s_<book>_\
&_;s_.*\n__;s_\(.*</book>\).*_\1_' file
答え2
そしてperl
:
#!/usr/bin/env perl
use strict;
use warnings;
use v5.10;
my @lines = (1, 2, 4);
while(<>) {
next unless $. ~~ @lines;
chomp;
s#.*?(<book>.*</book>).*#$1#;
say
}