cut / awkの代わりにbash変数置換を使用する

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を復元する必要があります(または、コマンド置換でこれを実行して、フィールドの値を取得すると、末尾の改行が削除されます)。

  • この例は単独で機能しますが(WindowsのGit bash内)、findコマンドからパイプすると、次のエラーが発生します:echo: write error: Bad address
  • わかりました、次のようになります。毎回unset IFSする必要があります。
  • 回答

    フィードスピードアップするためのawkへのリスト:

    awk -F "/" "{print $2}" < <(find /usr) awk -F "/" "{print $2}" < inputfile 

    デモンストレーション:

    time awk -F "/" "{print $2; SUM++} END {print "number of directories found: " SUM}" < <(find /usr -type d) usr usr . . number of directories found: 16748 real 0m8.910s user 0m0.050s sys 0m0.050s 

    回答

    このawk / sed /の代わりに、「dirname」コマンドを使用しないのはなぜですか。カットする?

    filename=./foo/bar/baz.xml dirname $filename 

    歩留まり:

    ./foo/bar 

    コメント

    • この場合、完全なディレクトリパスではなく、直接のディレクトリを探していました。

    コメントを残す

    メールアドレスが公開されることはありません。 * が付いている欄は必須項目です