多行替换以获得树视图

Multiline substitution to obtain a tree view

我有一个 bash 脚本,它使用 sed 和 `awk:

从特定输入生成以下输出
# ├── CHILDA1
# │  └── CHILDB1
# │  └── CHILDB2
# │  └── CHILDB3
# │  └── CHILDB4
# │  └── CHILDB5
# │  └── CHILDB6
# │     └── CHILDC1
# │     └── CHILDC2
# │  └── CHILDB7
# ├── CHILDA2
# └──────────────

有没有办法替换嵌套连接器,如果它们不是最后一个,以获得这样的东西?

# ├──┐CHILDA1
# │  ├── CHILDB1
# │  ├── CHILDB2
# │  ├── CHILDB3
# │  ├── CHILDB4
# │  ├── CHILDB5
# │  ├──┐CHILDB6
# │  │  ├── CHILDC1
# │  │  └── CHILDC2
# │  └── CHILDB7
# ├── CHILDA2
# └──────────────

第一个输出是通过简单的单行替换获得的,我想第二个输出需要在同一列(字符位置)检查上面的行。我不知道tree如何处理这个,但我想得到的结果非常相似。

https://en.wikipedia.org/wiki/Box_Drawing

获得的Unicode字符

从下往上处理文件会更容易。这可以使用 tac.

来实现

通过@flags,以下跟踪尚未遇到父级的子级的位置。

tac |
perl -CSD -Mutf8 -pe'
   if ( /[└├]/ ) {
      my $i = $-[0];         # Position of the match.
      substr($_, $i, 1, "├") if $flags[$i];
      $flags[$i] = 1;

      my $j = $i+3;          # Position of its children.
      substr($_, $j, 1, "┐") if $flags[$j];
      $flags[$j] = 0;

      while ( $i-- ) {
         substr($_, $i, 1, "│") if $flags[$i];
      }
   }
' |
tac

输出

# ├── CHILDA1
# │  ├── CHILDB1
# │  ├── CHILDB2
# │  ├── CHILDB3
# │  ├── CHILDB4
# │  ├── CHILDB5
# │  ├──┐CHILDB6
# │  │  ├── CHILDC1
# │  │  └── CHILDC2
# │  └── CHILDB7
# ├── CHILDA2
# └──────────────

全部在 Perl 中:

perl -CSD -Mutf8 -e'
   my @lines = reverse <>;

   for ( @lines ) {   
      if ( /[└├]/ ) {
         my $i = $-[0];         # Position of the match.
         substr($_, $i, 1, "├") if $flags[$i];
         $flags[$i] = 1;

         my $j = $i+3;          # Position of its children.
         substr($_, $j, 1, "┐") if $flags[$j];
         $flags[$j] = 0;

         while ( $i-- ) {
            substr($_, $i, 1, "│") if $flags[$i];
         }
      }
   }

   print reverse @lines;
'