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

На мой взгляд, макросы - это плохая привычка от C. Хотя они могут быть полезны для некоторых, я не вижу реальной потребности в них, когда есть typedefs и шаблоны. Шаблоны являются естественным продолжением объектно-ориентированного программирования. Вы можете сделать намного больше с шаблонами ...

Рассмотрим это ...

int main()
{
    SimpleList lstA;
    //...
    SimpleList lstB = lstA; //would normally give an error after trying to compile
}

Чтобы сделать преобразование, вы можете использовать то, что называется конструктором преобразования и конструктор последовательности (посмотрите на конец) по довольно полному примеру для списка:

#include 

template
class SimpleList
{
public:
    typedef T value_type;
    typedef std::size_t size_type;

private:
    struct Knot
    {
        value_type val_;
        Knot * next_;
        Knot(const value_type &val)
        :val_(val), next_(0)
        {}
    };
    Knot * head_;
    size_type nelems_;

public:
    //Default constructor
    SimpleList() throw()
    :head_(0), nelems_(0)
    {}
    bool empty() const throw()
    { return size() == 0; }
    size_type size() const throw()
    { return nelems_; }

private:
    Knot * last() throw() //could be done better
    {
        if(empty()) return 0;
        Knot *p = head_;
        while (p->next_)
            p = p->next_;
        return p;
    }

public:
    void push_back(const value_type & val)
    {
        Knot *p = last();
        if(!p)
            head_ = new Knot(val);
        else
            p->next_ = new Knot(val);
        ++nelems_;
    }
    void clear() throw()
    {
        while(head_)
        {
            Knot *p = head_->next_;
            delete head_;
            head_ = p;
        }
        nelems_ = 0;
    }
    //Destructor:
    ~SimpleList() throw()
    { clear(); }
    //Iterators:
    class iterator
    {
        Knot * cur_;
    public:
        iterator(Knot *p) throw()
        :cur_(p)
        {}
        bool operator==(const iterator & iter)const throw()
        { return cur_ == iter.cur_; }
        bool operator!=(const iterator & iter)const throw()
        { return !(*this == iter); }
        iterator & operator++()
        {
            cur_ = cur_->next_;
            return *this;
        }
        iterator operator++(int)
        {
            iterator temp(*this);
            operator++();
            return temp;
        }
        value_type & operator*()throw()
        { return cur_->val_; }
        value_type operator*() const
        { return cur_->val_; }
        value_type operator->()
        { return cur_->val_; }
        const value_type operator->() const
        { return cur_->val_; }
    };
    iterator begin() throw()
    { return iterator(head_); }
    iterator begin() const throw()
    { return iterator(head_); }
    iterator end() throw()
    { return iterator(0); }
    iterator end() const throw()
    { return iterator(0); }
    //Copy constructor:
    SimpleList(const SimpleList & lst)
    :head_(0), nelems_(0)
    {
        for(iterator i = lst.begin(); i != lst.end(); ++i)
            push_back(*i);
    }
    void swap(SimpleList & lst) throw()
    {
        std::swap(head_, lst.head_);
        std::swap(nelems_, lst.nelems_);
    }
    SimpleList & operator=(const SimpleList & lst)
    {
        SimpleList(lst).swap(*this);
        return *this;
    }
    //Conversion constructor
    template
    SimpleList(const SimpleList &lst)
    :head_(0), nelems_(0)
    {
        for(typename SimpleList::iterator iter = lst.begin(); iter != lst.end(); ++iter)
            push_back(*iter);
    }
    template
    SimpleList & operator=(const SimpleList &lst)
    {
        SimpleList(lst).swap(*this);
        return *this;
    }
    //Sequence constructor:
    template
    SimpleList(Iter first, Iter last)
    :head_(0), nelems_(0)
    {
        for(;first!=last; ++first)
            push_back(*first);


    }
};

Посмотрите на информацию cplusplus.com на шаблоны ! Вы можете использовать шаблоны для выполнения так называемых черт, которые используются, имеет своего рода документацию для типов и т. Д. Вы можете сделать гораздо больше с шаблонами, чем возможно с помощью макросов!

2
задан Michael Roland 2 March 2019 в 07:25
поделиться

3 ответа

Вот возможное решение с использованием 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
0
ответ дан melpomene 2 March 2019 в 07:25
поделиться

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

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

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

tree -Fa --dirsfirst helloworld | sed 's/\(.*│\)\s*└──.*/&\n\1/'
0
ответ дан potong 2 March 2019 в 07:25
поделиться

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

$ cat file | awk '1; match([110],/^((\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([111],/^[[:space:]]*(│[[:space:]]+)+└/){ print substr([111],1,RLENGTH-1) }'

и с GNU sed: [ 116]

$ cat file | sed -En 'p; s/^((\s*│)+)\s+└.*/\1/p'
0
ответ дан Ed Morton 2 March 2019 в 07:25
поделиться
Другие вопросы по тегам:

Похожие вопросы: