中かっこに基づいて行を複数の部分に分割しますか?

中かっこに基づいて行を複数の部分に分割しますか?

次の形式の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

grepPCREサポートで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

関連情報