
パスから最後の2つのディレクトリをどのように削除できますか?
パスの例:
./dir1/dir2/file-example.json
私が望む外観は次のとおりです。
./dir1/
答え1
パスが可変の場合は、専用ツールを使用することをお勧めします。
たとえば、次のようになりますzsh
。
file=./dir1/dir2///file-example.json
parent=$file:h:h
(頭の頭)。
またはbash
GNUユーティリティを使用してください。
IFS= read -rd '' parent < <(
dirname -z -- "$file" | xargs -r0 dirname -z --)
これにより、sed
アルゴリズムを手動で実装する必要があり、dirname
ORのようにzsh
すべてのケースをうまく処理したい場合は:h
複雑になります。考慮すべき事項:
- 末尾のエントリは無視する必要があります(ただし、入力ファイルがまたは
/
の場合はすべてではありません)。/
///
- 2つ以上の異なるシーケンスは、いくつかのシステムで特別な処理が必要な場合を除いて、単一のシーケンス
/
と同じように処理する必要があります(説明のために上記の例に追加した理由を説明しています)。/
//foo/bar
//
///
- ディレクトリ名は
foo
次のようにする必要があります。.
- ディレクトリ名は
/
次のようにする必要があります。/
- ファイルパスには、NUL以外のバイトのシーケンスを含めることができます。これには、有効な文字を形成しないか、改行を表さないバイトシーケンスが含まれます。パスは LINE_MAX より長い場合があります (一部の
sed
実装ではこれより長い行を処理しません)。
sed
/localeで使用し-z
て呼び出す限り、GNU実装を使用してこれを行うことは可能ですが、これは簡単ではありません。C
POSIX
ファイルの親ディレクトリの親ディレクトリを見つけるには、file-example.json
次のようにします。
parents=(*/**/file-example.json(ND:h:h))
zshから。または、bash
4.4+およびGNUユーティリティを使用してください。
readarray -td '' parents < <(
find . -mindepth 2 -name file-example.json -print0 |
LC_ALL=C gawk -F/ -v RS='\0' -v ORS='\0' '
{NF -= 2; print}'
)
$parents
これらのディレクトリを配列にインポートします。