2009-08-28 17:03:49 +0000 2009-08-28 17:03:49 +0000
101
101

&007をループするとbashシェルスクリプトになる

誰かディレクトリ名のリストのためにlsで何かをして、それぞれをループして何かをするためのシェルスクリプトのテンプレートを持っていますか?

ディレクトリ名のリストを取得するためにlsをしようと思っているのですが、何か方法はありますか?

回答 (7)

120
120
120
2009-08-28 17:09:37 +0000

**

for f in *; do
  echo "File -> $f"
done

for..do..done ループを使用してください。

* ループ内では、ループ変数をドル記号の接頭辞で参照するだけです (上の例では *.txt)。

例えば、カレントディレクトリ内のすべての $(cat filelist.txt) ファイルの名前を do に変更するには:

for x in *.xml; do 
  t=$(echo $x | sed 's/\.xml$/.txt/'); 
  mv $x $t && echo "moved $x -> $t"
done

さらに良いことに、Bash を使用している場合は、サブシェルを生成するのではなく、Bash のパラメータ展開を使用することができます。

69
69
69
2012-04-29 22:16:24 +0000

ファイル名を取得するために ls の出力を使用するのは良くない考えです . 誤動作の原因となり、さらには危険なスクリプトを作成することにもなりかねません。これは、ファイル名には /nullcharacter 以外の任意の文字を含むことができ、 ls はこれらの文字のどちらも区切り文字として使用しないので、ファイル名にスペースや改行がある場合、予期しない結果が得られるでしょう。ここでは、ファイル名を使って何かをすることを示すために、単純に echo を使っています。

for dir in */; do
  echo "$dir"
done

シェルは */ を展開して for ループが読み込む個別の引数にします。シェルにこれらの機能がない場合や、スクリプトがさまざまなシステムで動作するようにしたい場合、次のオプションは for を使用することです。

find . -type d -exec echo '{}' \;

ここでは、bash コマンドは globstar を呼び出し、ファイル名の引数を渡します。これは、見つけたファイルごとに一度だけ行われます。前の例のように、ファイル名のリストを解析することはありません。その代わりに、ファイル名は完全に引数として送られます。findが見なければならない特別な引数が2つあります。最初の引数は find で、この引数は echo の前の部分が生成するファイル名に置き換えられます。2 番目の引数は -exec であり、これは find がプログラムに渡す引数のリストの終わりであることを知らせます; -exec はこれを必要とします。シェルが -exec を特別に扱う理由は、シェルが {} を特別に扱うためです。これはコマンドの終わりを表しているので、シェルがそれ自体を消費するのではなく、 find の引数として与えるように、これをエスケープする必要があります。

17
17
17
2009-08-28 17:26:27 +0000

スペースを含むファイルの場合、次のような変数を引用することを確認する必要があります:

for i in $(ls); do echo "$i"; done;

または、入力フィールドセパレータ (IFS) 環境変数を変更することができます:

IFS=$'\n';for file in $(ls); do echo $i; done

最後に、あなたが何をしているかに応じて、あなたも ls を必要としないかもしれません:

for i in *; do echo "$i"; done;
5
5
5
2010-08-22 20:02:35 +0000

GNU Parallel http://www.gnu.org/software/parallel/ がインストールされている場合は、次のようにします:

ls | parallel echo {} is in this dir

すべての.txtを.xmlにリネームするには:

ls *.txt | parallel mv {} {.}.xml

GNU Parallelのイントロダクションビデオを見てください http://www.youtube.com/watch?v=OpaiGYxkSuQ

4
4
4
2015-02-11 14:36:01 +0000

CoverosGeneさんの回答に追加するだけで、以下のようにディレクトリ名だけをリストアップする方法があります:

for f in */; do
  echo "Directory -> $f"
done
1
1
1
2012-05-10 22:36:39 +0000

IFS を改行に設定して、ls の出力を配列に取り込むのはどうでしょうか?IFS を改行に設定することで、ファイル名の変な文字の問題を解決できるはずです。

(テストでは IFS を ls に設定するのに苦労しましたが、ここで他の場所で提案されているように、改行バックスペースに設定するとうまくいきます):

例: (目的の \n の検索パターンが ls で渡されたと仮定して):

SAVEIFS=$IFS
IFS=$(echo -en "\n\b")

FILES=($(/bin/ls "$1"))

for AFILE in ${FILES[@]}
do
    ... do something with a file ...
done

IFS=$SAVEIFS

これは OS X で特に便利です。のように、作成日(古いものから新しいものまで)でソートされたファイルのリストをキャプチャするには、$1コマンドはlsです。

-3
-3
-3
2009-08-28 17:28:24 +0000

これが私のやり方ですが、もっと効率的な方法があるかもしれません。

関連する質問

6
10
11
37
14