Добавить бар между каталогами с помощью sed / awk - PullRequest
0 голосов
/ 02 марта 2019

Я использую утилиту tree для рекурсивного показа каталогов, подобных этому:

$ tree -F -a --dirsfirst project
project
├── my_app/
│   └── __init__.py
└── tests/
    ├── integration/
    │   ├── __init__.py
    │   └── test_integration.py
    └── unit/
        ├── __init__.py
        └── test_sum.py

$ tree -F -a --dirsfirst helloworld
helloworld
├── helloworld/
│   ├── __init__.py
│   ├── helloworld.py
│   └── helpers.py
├── tests/
│   ├── helloworld_tests.py
│   └── helpers_tests.py
├── .gitignore
├── LICENSE
├── README.md
├── requirements.txt
└── setup.py

Я бы хотел передать это в sed или awk, чтобывнесите небольшое изменение: в конце списка любого каталога , будет вставлен символ новой строки + литерал |:

project/
├── my_app/
│   └── __init__.py
│
└── tests/
    ├── integration/
    |   ├── __init__.py
    |   └── test_integration.py
    |
    └── unit/
        ├── __init__.py
        └── test_sum.py

helloworld/
├── helloworld/
│   ├── __init__.py
│   ├── helloworld.py
│   └── helpers.py
│
├── tests/
│   ├── helloworld_tests.py
│   └── helpers_tests.py
│
├── .gitignore
├── LICENSE
├── README.md
├── requirements.txt
└── setup.py

Как я могу сделать эту замену?


Текущая попытка и логика: новая строка + | вставляется после начального и перед начальным ├── (необязательный пробел перед обоими):

tree -F -a --dirsfirst helloworld | sed -E 's/^\s*\│.*\n\s*\├──/???/g'

Застрял там ужасно- в 100 раз более опытный в Python re и немного grep, чем sed / awk.

Ответы [ 3 ]

0 голосов
/ 02 марта 2019

Использование cat file вместо двух команд дерева в вашем вопросе с GNU awk:

$ cat file | awk '1; match($0,/^((\s*│)+)\s+└/,a){ print a[1] }'
project
├── my_app/
│   └── __init__.py
│
└── tests/
    ├── integration/
    │   ├── __init__.py
    │   └── test_integration.py
    │
    └── unit/
        ├── __init__.py
        └── test_sum.py

helloworld
├── helloworld/
│   ├── __init__.py
│   ├── helloworld.py
│   └── helpers.py
│
├── tests/
│   ├── helloworld_tests.py
│   └── helpers_tests.py
│
├── .gitignore
├── LICENSE
├── README.md
├── requirements.txt
└── setup.py

и с любым awk:

$ cat file | awk '1; match($0,/^[[:space:]]*(│[[:space:]]+)+└/){ print substr($0,1,RLENGTH-1) }'

и с GNU sed:

$ cat file | sed -En 'p; s/^((\s*│)+)\s+└.*/\1/p'
0 голосов
/ 02 марта 2019

Это может работать для вас (GNU sed):

sed 's/\(.*│\)\s*└──.*/&\n\1/' file

Где файл может быть stdin из канала команды дерева, например

tree -Fa --dirsfirst helloworld | sed 's/\(.*│\)\s*└──.*/&\n\1/'
0 голосов
/ 02 марта 2019

Вот возможное решение с использованием Perl:

perl -pe 'if (/│.*└/) { print; s/ *└.*// }'

Идея:
Для каждой строки, содержащей где-то после и , обрезать и все последующие символы и все предшествующие пробелы, затем выведите эту измененную строку.

Эффект:

│    │   └── foo.xyz

будет сопровождаться новой строкой, содержащей только

│    │

в выводе.

Sed версия:

sed '/│.*└/{p;s/ *└.*//}'

Для вашего образца вводит следующий вывод:

$ tree -F -a --dirsfirst project
project
├── my_app/
│   └── __init__.py
│
└── tests/
    ├── integration/
    │   ├── __init__.py
    │   └── test_integration.py
    │
    └── unit/
        ├── __init__.py
        └── test_sum.py

$ tree -F -a --dirsfirst helloworld
helloworld
├── helloworld/
│   ├── __init__.py
│   ├── helloworld.py
│   └── helpers.py
│
├── tests/
│   ├── helloworld_tests.py
│   └── helpers_tests.py
│
├── .gitignore
├── LICENSE
├── README.md
├── requirements.txt
└── setup.py
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...