パスを分割しようとしましたが、正しいコマンドを受信できませんでした。
つまり、/bin/bash/test/path/to/split
文字列で区切られた2つの部分に分割/切断する必要があります/to/
。つまり、文字列に分割する必要があります。
期待される出力:/bin/bash/test/path
および/split
切り取りコマンドオプションを試しましたが、うまくいきませんでした。
答え1
cut
単一文字の1区切り文字のみが許可されます。
bash
変数は次のように処理できます。
❯ testfull="/bin/bash/test/path/to/split"
❯ testpre="${test%/to/*}"
❯ testpost="${test#*/to/}"
❯ echo "$testpre is separate from $testpost"
/bin/bash/test/path is separate from split
%pattern*
パターンの後ろのすべてとパターンの前のすべてを削除します#*pattern
。パターンの複数のインスタンスがある場合は、#
2%
倍にするか、最初または最後のインスタンスを選択できます。
awk
文字列区切り文字を指定-F
し、必要な残りのセグメントを選択できます。
❯ echo "/bin/bash/test/path/to/split" | awk -F'/to/' '{print $1" separate from "$2}'
/bin/bash/test/path separate from split
¹GNUを含む多くのcut
実装では、cut
シングルバイト文字に制限されています。
答え2
zsh
シェルでは、パラメータ拡張フラグを使用して任意の区切り文字で文字列を分割できますs
。
$ file=$'/path/to//to/dir/and\nor/to/file'
$ parts=( "${(@s[/to/])file}" )
$ typeset parts
parts=( /path '' $'dir/and\nor' file )
$ printf ' - <%s>\n' "$parts[@]"
- </path>
- <>
- <dir/and
or>
- <file>
ファイルパスには/to/
2つの連続したエントリが複数回含まれており、ここでは心配する必要がある潜在的なトラップを警告するために改行文字が選択される人工的な例です。
sは、空の@
要素(ここでは連続した項目間の要素)を保存するために引用符と結合されます/to/
。
j
パラメータ拡張フラグを使用して、フラグメントを一緒に結合できます。
$ print -r -- ${(j[/to/])parts}
/path/to//to/dir/and
or/to/file
perl
bash4.4+では、以下を削除して分割などのいくつかの操作を実行できます。
$ file=$'/path/to//to/dir/and\nor/to/file'
$ readarray -td '' parts < <(perl -l0se 'print for split /\Q$s\E/, $file, -1' -- -file="$file" -s=/to/)
$ typeset -p parts
declare -a parts=([0]="/path" [1]="" [2]=$'dir/and\nor' [3]="file")
これはperl
文字単位ではなくバイト単位で機能します。ここで決定された区切り文字の始まりと終わりのエンコーディングは/
他の文字では見つからないことを保証しますが、途中の一部の文字は他の区切り文字によって破損する可能性があります。
では、zsh
次のトピックも参照してください。
$ file=/bin/bash/test/path/to/split
$ print -r -- $file:h:h
/bin/bash/test/path
(エドh
のエドh
)
$ print -r -- $file:t
split
(t
アル)。
csh/tcsh と同じです。bash
また、これをサポートします:h
。:t
修飾子ただし、これは歴史的拡張に限定され、パラメータ拡張には適用できません。