web-dev-qa-db-ja.com

ディレクトリのBash For-Loop

簡単な背景:

$ ls src
file1  file2  dir1  dir2  dir3

脚本:

#!/bin/bash

for i in src/* ; do
  if [ -d "$i" ]; then
    echo "$i"
  fi
done

出力:

src/dir1
src/dir2
src/dir3

しかし、私はそれを読んで欲しい:

dir1
dir2
dir3

今、私は出力をsed/awkして "src /"を削除できることに気付きましたが、これについてもっと良い方法があるかどうか知りたいです。代わりにfind + while-loopを使用する可能性があります。

32
BassKozz

代わりにecho行に対してこれを実行します。

 echo $(basename "$i")
21
Gonzalo

外部プロセスをフォークする必要はありません:

echo "${i##*/}"

「最長一致プレフィックスを削除する」 パラメータ展開 を使用します。 */はパターンであるため、文字列の先頭から最後のスラッシュまでをすべて削除します。 $iの値にスラッシュがない場合、"$i"と同じです。

この特定のパラメーター展開は POSIXで指定 であり、元のBourne Shellのレガシーの一部です。すべてのBourneライクシェルでサポートされています(shashdashkshbash zshなど)。機能豊富なシェルの多く(kshbash、およびzsh)には、外部プロセスを使用せずにさらに処理できる拡張機能があります。

13
Chris Johnsen

スクリプトの開始時にcdを実行する場合、スクリプトの終了時に元に戻す必要があります。

#!/bin/bash

cd src
for i in * ; do
  if [ -d "$i" ]; then
    echo "$i"
  fi
done
8
Mark Ransom

basenameを次のように使用します。

if [ -d "$i" ]; then
    basename "$i"
fi
5
codaddict