テキスト処理にUnixツールを使用する

テキスト処理にUnixツールを使用する

次の形式のファイルがあります。

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(つまり、次のコマンドを実行しないでください)。
  • 入力行が空の場合は、それを印刷し(空白行)、次のコマンドを実行せずに次の行に進みます。
  • 上記のいずれかの項目と一致しない各行について、各フィールドに対して最大しかし含まれていません最後に、対応するデバイス名と改行文字が印刷されますが、|改行文字は含まれません。最後のフィールドは改行文字で印刷されますが、印刷されません|

関連情報