Intereting Posts
Не удалось установить открытое CV в Ubuntu 12.04 ssh passwordless не работает для вновь созданного пользователя с помощью команды «useradd» Какова цель кажущихся непригодными для памяти сопоставлений в Linux? bash: получить последний stdout Как просмотреть список ранее выполненных запросов MySQL в формате live feed? Открытие многих туннелей, ввод пароля только один раз (все учетные записи в шлюзах имеют одинаковый проход) Как частично копировать файл с разбитого диска? Семантический запрос локальных данных Как я могу убедиться, что eth1 сразу же получит свой IP-адрес fe80 при запуске, даже если он физически не подключен? От скрипта Python до модуля ядра Logitech MX-510: некоторые дополнительные кнопки недоступны Ошибка сети с несколькими параллельными контейнерами докеров Как легко и безопасно обмениваться файлами в Linux-системе через Интернет? Есть ли способ задержать повторное соединение канала irssi во время повторного подключения до тех пор, пока не произойдет авторизация? Как использовать два операнда в левой части оператора сравнения в Bash

Сортировка файла при группировке отступов строк с их родителями (многоуровневые)

Все уровни должны быть отсортированы в алфавитном порядке (но должны быть сохранены с их родителем)

Пример файла:

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

Ожидаемый результат:

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

Следующая команда была использована, но она работает, только если файл имеет только два уровня в дереве.

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

Как я могу правильно отсортировать все уровни?

заранее спасибо

    Расширенное решение 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 

    Awk решение:

    Образец infile содержимого (4 уровня):

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

     awk '{ offset = gsub(/ /, ""); if (offset == 0) { items[NR] = $1 } else if (offset > prev_ofst) { items[NR] = items[NR-1] "." $1 } else { prev_item = items[NR-1]; gsub("(\\.[^.]+){" int(prev_ofst / offset) "}$", "", prev_item); items[NR] = prev_item "." $1 } prev_ofst = offset; } END{ asort(items); for (i = 1; i <= NR; i++) { gsub(/[^.]+\./, " ", items[i]); print items[i] } }' infile 

    Выход:

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

    работает на любую глубину

     #!/usr/bin/python3 lines = open('test_file').read().splitlines() def yield_sorted_lines(lines): sorter = [] for l in lines: fields = l.split('\t') n = len(fields) sorter = sorter[:n-1] + fields[n-1:] yield sorter, l prefixed_lines = yield_sorted_lines(lines) sorted_lines = sorted(prefixed_lines, key=lambda x: x[0]) for x, y in sorted_lines: print(y) 

    Или трубопровод

     awk -F'\\t' '{a[NF]=$NF; for (i=1; i<=NF; ++i) printf "%s%s", a[i], i==NF? "\n": "\t"}' file| sort | awk -F'\\t' -vOFS='\t' '{for (i=1; i 
     sed '/^ /{H;$!d};x;1d;s/\n/\x7/g' | sort | tr \\a \\n 

    /continuation/{H;$!d};x;1d (или /firstline/! т. Д.) – это бред, он проваливается только тогда, когда в буфере обнаруживается полная строчка.

    Если в конце вы можете получить однострочный заголовок, добавьте ${p;x;/\n/d} чтобы сделать двойной насос, необходимый для этого.