次の形式のファイルがあります。
abc|xyz|mno
x up x
up up x
x x up
abc|xyz|mno
x x x
up x x
....
....
デフォルトでは、ファイルの最初の行はデバイス名、(|ed)
次の行はデバイスの状態です。
出力を次の形式にしたいと思います。
abc,x|xyz,up|mno,x
abc,up|xyz,up|mno,x
abc,x|xyz,x|mno,up
abc,x|xyz,x|mno,x
abc,up|xyz,x|mno,x
....
....
アドバイスはありますか?
答え1
CPANのモジュールperl
で使用できる場合:List::MoreUtils
$ perl -MList::MoreUtils=pairwise -F'\|' -anle '
print and next if /^$/;
@dev = @F and next if @F > 1;
print join "|", pairwise {"$a,$b"} @dev,@{[split]};
' file
abc,x|xyz,up|mno,x
abc,up|xyz,up|mno,x
abc,x|xyz,x|mno,up
abc,x|xyz,x|mno,x
abc,up|xyz,x|mno,x
外部モジュールを使用したくない場合:
$ perl -F'\|' -anle '
print and next if /^$/;
@dev = @F and next if @F > 1;
@state = split;
print join "|", map {"$dev[$_],$state[$_]"} 0..$#dev;
' file
答え2
awk
入力が説明と正確に一致する場合は、次のコマンドを使用して必要な操作を実行できます(ただしエラーチェックは実行しません)。
awk '/\|/ {split($0, devices, "|"); next} /^$/ {print; next}
{for (i=1; i<NF; i++) printf "%s,%s|", devices[i], $i; printf "%s,%s\n", devices[NF], $NF}'
- 入力行にaが含まれている場合は、
|
s|
から「devices」という配列に分割します。 (\|
通常の|
手段を使用しているため使用する必要があります。または、良い/cat|dog/
。 ) 入力データラインを実行し続けますnext
(つまり、次のコマンドを実行しないでください)。 - 入力行が空の場合は、それを印刷し(空白行)、次のコマンドを実行せずに次の行に進みます。
- 上記のいずれかの項目と一致しない各行について、各フィールドに対して最大しかし含まれていません最後に、対応するデバイス名と改行文字が印刷されますが、
|
改行文字は含まれません。最後のフィールドは改行文字で印刷されますが、印刷されません|
。