インデントされた行を親行とグループ化しながらファイルを並べ替える(複数レベル)

インデントされた行を親行とグループ化しながらファイルを並べ替える(複数レベル)

すべてのレベルはアルファベット順にソートする必要があります(ただし、上位レベルで保存する必要があります)。

ファイルの例:

first
    apple
    orange
        train
        car
    kiwi
third
    orange
    apple
        plane
second
    lemon

予想される結果:

first
    apple
    kiwi
    orange
        car
        train
second
    lemon
third
    apple
        plane
    orange

次のコマンドが使用されましたが、ファイルがツリー内に2つのレベルしかない場合にのみ機能します。

sed '/^[^[:blank:]]/h;//!G;s/\(.*\)\n\(.*\)/\2\x02\1/' infile | sort | sed 's/.*\x02//'

すべてのレベルを正しくソートするにはどうすればよいですか?

事前にありがとう

ベストアンサー1

拡大するPython解決策:

サンプルinfileコンテンツ(レベル4):

first
    apple
    orange
        train
        car
            truck
            automobile
    kiwi
third
    orange
    apple
        plane
second
    lemon

sort_hierarchy.pyスクリプト:

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import sys
import re

with open(sys.argv[1], 'rt') as f:
    pat = re.compile(r'^\s+')
    paths = []

    for line in f:
        offset = pat.match(line)
        item = line.strip()

        if not offset:
            offset = 0
            paths.append(item)
        else:
            offset = offset.span()[1]
            if offset > prev_offset:
                paths.append(paths[-1] + '.' + item)
            else:
                cut_pos = -prev_offset//offset
                paths.append('.'.join(paths[-1].split('.')[:cut_pos]) + '.' + item)

        prev_offset = offset

    paths.sort()
    sub_pat = re.compile(r'[^.]+\.')
    for i in paths:
        print(sub_pat.sub(' ' * 4, i))

使用法:

python sort_hierarchy.py path/to/infile

出力:

first
    apple
    kiwi
    orange
        car
            automobile
            truck
        train
second
    lemon
third
    apple
        plane
    orange

おすすめ記事