次のように、$basename
2つの部分の出力$stem
合計を含む文字列を分割したいと思います。$ext
- この文字列は
"${stem}${ext}"
元の文字列と同じです$basename
。 - または空にすることができ
$stem
ます$ext
(文字列によって異なります$basename
)。 - 空でない場合は、
$ext
次から始めて.
もう含めることはできません。.
このためにシェル関数を書くことは難しくありません。しかし、そうする前にこれを実行できる標準のUnixコマンドがあるかどうかを知りたいです。
編集する:
FWIW、()スクリプトで私がコーディングした方法はzsh
次のとおりです。
stem=${basename%.*}
ext=${basename#"$stem"}
編集:タイプミス(${base#...
- > ${basename#...
)を修正し、Stephane Chazelasの提案(...#$stem
- > ...#"$stem"
)を統合しました。
答え1
Bashに含まれる一般的な文字列解析機能を使用すると、必要なものに非常に近い操作を実行できます。
$ F="foo.bar.baz"
$ echo ${F%.*}
foo.bar
$ echo ${F/*./.}
.baz
したがって、次のように整理できます。
$ $ F="foo.bar.baz"
$ stem=${F%.*}
$ ext=${F/*./.}
echo "${stem}${ext}"
foo.bar.baz
Bashのマニュアルページから
${F%.*}${parameter%word}
${parameter%%word}
Remove matching suffix pattern. The word is expanded to produce a pattern
just as in pathname expansion. If the pattern matches a trailing portion
of the expanded value of parameter, then the result of the expansion is
the expanded value of parameter with the shortest matching pattern (the
``%'' case) or the longest matching pattern (the ``%%'' case) deleted. If
parameter is @ or *, the pattern removal operation is applied to each
positional parameter in turn, and the expansion is the resultant list.
If parameter is an array variable subscripted with @ or *, the pattern
removal operation is applied to each member of the array in turn, and
the expansion is the resultant list.
${/*./.}
${parameter/pattern/string}
Pattern substitution. The pattern is expanded to produce a pattern just
as in pathname expansion. Parameter is expanded and the longest match of
pattern against its value is replaced with string. If pattern begins
with /, all matches of pattern are replaced with string. Normally
only the first match is replaced. If pattern begins with #, it must match
at the beginning of the expanded value of parameter. If pattern begins
with %, it must match at the end of the expanded value of parameter.
If string is null, matches of pattern are deleted and the / following
pattern may be omitted. If parameter is @ or *, the substitution operation
is applied to each positional parameter in turn, and the expansion
is the resultant list. If parameter is an array variable subscripted
with @ or *, the substitution operation is applied to each member of the
array in turn, and the expansion is the resultant list.
これらの機能については、以下で読むことができます。バッシュのマニュアルページ。
答え2
シェル変数を設定するコマンドはありません。なぜなら、変数はシェルプロセスの内部にあるので、自分のプロセス内の他のコマンドはそれを変更できないからです。
シェルを使用すると、次のことができます。
var=$(some-command)
コマンドの出力を検索します(末尾の改行なし)。ただし、コマンドの両方の結果が必要な場合は、より難しくなります。
これを行う1つの方法は次のとおりです。
eval "$(some-command)"
そのうち some-command は次の内容を出力します。
var1='something' var2='someotherthing'
ただし、尋ねる前にパスを取得してそれをディレクトリ、基本名、および拡張子(それが何を意味するか)に分割する標準コマンドはありません。
これで、シェル自体にはこの目的のための内部機能があります。たとえばcsh
、zsh
頭、尾、拡張を提供する修飾子があります。図zsh
:
file=/path/to/foo.bar/
head=$file:h
tail=$file:t
ext=$file:e
rest=$file:r
.
..
今、or/
など.bashrc
のファイルに対してこれが何であるべきかを考えてみたいかもしれませんfoo.tar.gz
。
今標準POSIX構文を探している場合は、すでに(ほぼ)それを持っています:rest=${file%.*}
。具体${file#$rest}
的に言ってくださいzsh
。 POSIX 構文では が必要でext=${file#"$rest"}
、それ以外の場合は$rest
パターンとして処理されます。文字(たとえば)$file
を含むパスを含めると、必要に応じて機能しない可能性があります。/
foo.d/bar
答え3
文字列に改行文字が含まれていない場合:
start cmd:> echo foo.bar.baz | sed 's/\(^.*\)\(\.[^\.]*$\)/\1/'
foo.bar
start cmd:> echo foo.bar.baz | sed 's/\(^.*\)\(\.[^\.]*$\)/\2/'
.baz
答え4
「foo.bar」としましょう。 ext が欠落しており、常に 2 ~ 3 つのピリオドがある場合は有効な出力です。アッ:
basename='foo.bar.baz'
stem=$(echo $basename | awk '{ split($1,a,"."); print a[1] "." a[2]; }')
ext=$(echo $basename | awk '{ split($1,a,"."); print "." a[3]; }');
echo $stem$ext