sed を使用して、先頭をすべて一致する数の代替文字列に置き換えます。

sed を使用して、先頭をすべて一致する数の代替文字列に置き換えます。

各行の先頭のボックス描画文字とスペースが一致する数のスペースに置き換えられるように、$tree --noreport$の出力を操作したいと思います。この文字に一致するパターンを作成すると、sedがUnicodeエスケープシーケンスを認識しないため、文字列がラップされ^\\(\u2500\\|\u2514\\|\u251C\\| \\)*\u2500ます。$'...'このパターンは、tree --noreport最初の行を除くすべての出力行に表示されます。一致するすべての文字列のすべての文字を空白に置き換える必要があります。

入力例:

.
├── docs
│   ├── jokes
│   │   └── knock_knock.txt
│   └── work
├── images
└── .profile

出力例:

.
    docs
        jokes
            knock_knock.txt
        work
    images
    .profile

これで、私の目的のためにファイルまたはフォルダ名が始まる場所を明確にする必要があることに気づきました(ファイルまたはフォルダ名は1つ以上のスペースで始まる可能性があります)。したがって、出力は実際には次のようになります。

.
    /docs
        /jokes/
            /knock_knock.txt
        /work
    /images
    /.profile

私が提供したパターンの終わりは、\u2500実際にはツリー形式とファイル/フォルダ名の始まりを区別します。

答え1

次のループで一度に1つずつ交換できます。

tree --noreport | sed $'
  :1
    s/^\\( *\\)\\([\ua0\u2500\u2502\u2514\u251C]\\)\\([\ua0\u2500\u2502\u2514\u251C ]*\u2500 \\)/\\1 \\3/
  t1
  s|\u2500 |  /|'

(少なくとも私のバージョンの出力には\ua0(単純な空白ではない)と\u2502(あなたの例にも示されています)がありません。)tree

"─ "名前の前にこれらの文字を含むファイルがある場合は、だまされています。

別の方法(実際に挿入したいと/呼び出すディレクトリに対応するtreeエントリがないと仮定):最初のエントリの後に挿入し、ループ内"─ "の最初の文字の前のすべての文字を空白に置き換えます。/"\u2500 "/

tree --noreport | sed '
  s|'$'\u2500'' |&/|;t1
  b
  :1
    s|^\( *\)[^ /]|\1 |
  t1'

次のコマンドを使用する方が簡単ですperl

tree --noreport | perl -C -pe 's{^.*?\x{2500} }{" " x length($&) . "/"}e'

答え2

bash以下は、最上位ディレクトリにある名前を繰り返し出力する関数です。

mytree () (
    topdir="${1-.}"
    indent="${2-0}"

    shopt -s nullglob
    shopt -s dotglob

    # output directory name
    printf "%${indent}s'%s'/\n" "" "${topdir##*/}"

    indent=$(( indent + 4 ))

    for name in "$topdir"/*; do
        if [ -h "$name" ]; then
            # output symbolic link name and target
            printf "%${indent}s'%s' --> '%s'\n" "" "${name##*/}" "$( readlink -- "$name" )"
        elif [ -d "$name" ]; then
            # recurse into directories
            mytree "$name" "$indent"
        else
            # output other type of name (not directory or symbolic link)
            printf "%${indent}s'%s'\n" "" "${name##*/}"
        fi
    done
)

この関数は、mytree処理する最上位ディレクトリである1つの引数(2番目の引数は再帰呼び出しにのみ使用されます)を使用します。引数が指定されていない場合は、現在のディレクトリをリストされている最上位ディレクトリとして使用します。

出力は次のとおりです。

'Work'/
    'Data'/
        's3wes.all.tab.frq.counts'
        's3wes.con.tab.frq.counts'
        'sullivan.txt'
    'Development'/
        'ENA-submission'/
            '.git'/
                'COMMIT_EDITMSG'

など。

つまり、名前は一重引用符で囲まれ、ディレクトリの後には名前が付けられます/。また、シンボリックリンクは次のように表示されます。

'embl-validator.jar' --> 'embl-api-validator-1.1.158.jar'

3つの呼び出しを変更すると、出力形式を簡単に変更できますprintf

関連情報