bash変数置換を使用して、区切り文字に基づいて変数の一部を抽出できますか?ファイル名の直接のディレクトリ名(この場合はfoo
)を取得しようとしています。
$ filename=./foo/bar/baz.xml
私は
echo $filename | cut -d "/" -f 2
または
echo $filename | awk -F "/" "{print $2}"
のようなことができることを知っていますがそれは ” s複数のファイル名のawk
/ cut
のフォークが遅くなっています。
さまざまなソリューションのプロファイリングを少し行いました。 、実際のファイルを使用:
echo |カット:
real 2m56.805s user 0m37.009s sys 1m26.067s
エコー| awk:
real 2m56.282s user 0m38.157s sys 1m31.016s
@steeldriverの変数置換/シェルパラメーター展開:
real 0m0.660s user 0m0.421s sys 0m0.235s
@jai_sのIFSラングリング:
real 1m26.243s user 0m13.751s sys 0m28.969s
どちらの提案も私の既存のアイデアを大幅に改善しましたが、変数の置換はそうではないため、最速です。新しいプロセスをフォークする必要があります。
コメント
- gnu.org/software/bash/manual / html_node / …
- すべてのファイル名をawkの1回の呼び出しに送信すると、純粋なbashのどのソリューションよりも大幅に高速になります
- 配列を使用できません。一度にすべて実行してから、新しい配列に配置しますか?
回答
*/
tmp="${filename#*/}"
に一致する最短の先行サブストリングを削除してから、最長のサブストリングを削除できます/*
回答
echo $f a/b/c $ (IFS="/";set $f; echo $1) a $ (IFS="/";set $f; echo $2) b $ (IFS="/";set $f; echo $3) c
ワイルドカードを使用すると機能するようです二重引用符または一重引用符-
f="a?b?c" $(IFS="?"; set $f; echo $1) a echo $f a*b*c (IFS="*"; set $f; echo $1) a
はい、IFSの設定をデフォルトに戻す必要があります
unset IFS
コメント
- ああ、私はそれが好きです。
- これも通常は私の好みの方法ですが、Bashに注意してください。この構文を使用する場合は、
$1
から$9
のみをサポートします。 10番目以降の引数については、${10}
形式を使用する必要があります。 - 'は
にはワイルドカードが含まれています。そして、後でIFS
を復元する必要があります(または、コマンド置換でこれを実行して、フィールドの値を取得すると、末尾の改行が削除されます)。
echo: write error: Bad address
。unset IFS
する必要があります。