次の形式の1行ファイルがあります。
{port1 dev1 M1 s} {port1 dev1 M1 s} {port3 dev2 M1 g} {port1 dev1 M1 d} {port1 dev1 M3 g} ...
以下に示すように、この行とcatを中括弧{}に基づく出力ファイルに分割したいと思います。どうすればいいですか?
port1 dev1 M1 s
port1 dev1 M1 s
port3 dev2 M1 g
port1 dev1 M1 d
port1 dev1 M3 g
答え1
パールの使用:
perl -lne 'print for /{(.*?)}/g' file
port1 dev1 M1 s
port1 dev1 M1 s
port3 dev2 M1 g
port1 dev1 M1 d
port1 dev1 M3 g
またはsedを使用してください:
sed 's/{\([^}]*\)} */\1\n/; P;D' file
port1 dev1 M1 s
port1 dev1 M1 s
port3 dev2 M1 g
port1 dev1 M1 d
port1 dev1 M3 g
...
答え2
grep
PCREサポートでGNUを使用する:
grep -Po '{\K[^}]*'
または、少なくとも空白以外の文字を含む{}以外のシーケンスの場合:
grep -o '[^{}]*[^{}[:space:]][^{}]*'
そしてpcregrep
:
pcregrep -o1 '{(.*?)}'
{...}
sを入れ子にすることができる場合(ただしバランスが維持されている):
pcregrep -o1 '{((?:[^{}]+|(?0))*)}'
次のように入力すると:
{port1 {dev1 dev2} M1 s} {port1 dev1 M1 s}
それは以下を提供します:
port1 {dev1 dev2} M1 s
port1 dev1 M1 s
答え3
$ tr '}' '\n' <file | sed -E 's/^ ?\{//'
port1 dev1 M1 s
port1 dev1 M1 s
port3 dev2 M1 g
port1 dev1 M1 d
port1 dev1 M3 g
まず、}
各改行文字をtr
。これにより、sed
コマンドに処理するための別々の行が提供され、各行は空白で始まります{
。この文字はコマンドによって行の先頭から削除されますsed
。
同じことsed
:
sed -E -e 's/ ?\{//g' -e 'y/}/\n/'
コマンドはy
この例と同様に機能します。tr
GNUawk
またはを使用mawk
し、BSDを使用しないでくださいawk
。
$ awk -v RS='[{}]' '/[^[:blank:]]/' file
port1 dev1 M1 s
port1 dev1 M1 s
port3 dev2 M1 g
port1 dev1 M1 d
port1 dev1 M3 g
これは、データをまたはで区切られたレコードとして解釈し、タブまたはスペース以外の項目を{
含む}
各レコードを印刷します。
パールの使用:
$ perl -ne 'map { print "$_\n" } /{(.*?)}/g' file
port1 dev1 M1 s
port1 dev1 M1 s
port3 dev2 M1 g
port1 dev1 M1 d
port1 dev1 M3 g
これにより、print
与えられた正規表現を入力と一致させて、返された各要素にコマンドを適用します。また、このprint
コマンドは各要素が別々の行になるように改行文字を追加します。
答え4
GNU sedソリューション:
sed -e 's/} {/\n/g' -e 's/^{//' -e 's/}//' input-file > output-file