2009-11-06 11 views
28

私は名前を何かbashのファイルからファイル名のリストを読むにはどうすればよいですか?

find . -type f -mtime +15 > /tmp/filelist.txt 
for F in $(cat /tmp/filelist.txt) ; do 
    ... 
done; 

の同類を、入力ファイルの1行に1つずつ保存されている私の問題はfilelist.txtでそのファイル名でファイルのリストを処理するbashスクリプトを記述しようとしています上記切り取ら三つの異なるファイル名、mytextfile.txtにライン

my text file.txt 

を拡大していきますので、スペースが含まれていてもよいです。どうすれば修正できますか?

+1

を読んで、パイプ、ディレクトリエントリはまた、同様に、改行を含めることができますスペースやその他の不気味なキャラクターとして。ディレクトリエントリ(ファイル名)が持つことができないのは、 "/"と ""の文字だけです。 (スラッシュとヌル)。 – chris

+0

しかし、私が作業しているファイルは、私のLAN上でWindowsユーザがsamba共有にアクセスすることで作成されるので、ファイル名の奇妙さには限界があります – agnul

答えて

36

使用read

while read F ; do 
     echo $F 
done </tmp/filelist.txt 

代わりにシェルがあなたのリストを区切る方法を変更するためにIFSを使用します。

OLDIFS=$IFS 
IFS=" 
" 
for F in $(cat /tmp/filelist.txt) ; do 
    echo $F 
done 
IFS=$OLDIFS 

代わりに(@tangensにより示唆されるように)、にあなたのループの本体を変換します別のスクリプトを使用して、findの-execオプションを使用して、各ファイルが直接見つかった場合に実行します。

+0

私はそれを票決しましたが、私はこのスクリプトが非ASCII文字を含むパスで失敗することを発見しました。 – kakyo

-1

私はすなわち、あなたが完全に一時ファイルをスキップしてちょうど直接見つけるの結果を反復処理することができると信じていません。:

for F in $(find . -type f -mtime +15) ; do 
    ... 
done; 

は保証私の構文が正しいですが、私は概念が働くかなり確信していること。

編集:ファイル名のリストでファイルを処理する必要があり、上記のように単純にコマンドを組み合わせることができない場合は、IFS変数の値を変更することができます。内部フィールドセパレータ - bashがフィールドをどのように決定するかを変更します。デフォルトでは空白に設定されているので、改行、スペース、またはタブは新しいフィールドを開始します。改行のみを含むように設定した場合、以前と同じようにファイルを繰り返し処理できます。

+1

私はシェルがまだホワイトスペースで分離を行うと思いますか? –

+0

これを下げてください - オリジナルと同じ問題があります(スペースで分割) – DVK

+0

私は編集を行い、真ん中で電話をしなければなりませんでしたが、このサイトでは5分を待つのが長すぎると思います。 – qid

3

使用中は

echo $FILE | while read line 
do 
echo $line 
done 

を読む代わりに、エコー

+0

ファイルが1つしかない場合、シェルリダイレクトは 'cat'プロセスの生成を避けます。 –

0

の私は(私は通常、クロスプラットフォームであることをRubyやPythonで私のスクリプトを記述する任意の手段によって、bashの専門家ではないリダイレクト行うことができます)、私はあなたがそれを処理する前に各行のスペースをエスケープする正規表現のexprationを使用します。 Bashの正規表現については

:Rubyで似たような状況で http://www.linuxjournal.com/node/1006996

(csvファイルを処理し、それを使用する前に、各ラインのクリーンアップ):

File.foreach(csv_file_name) do |line| 
    clean_line = line.gsub(/()/, '\ ') 
    #this finds the space in your file name and escapes it  
    #do more stuff here 
end 
1

あなたがの-execパラメータを使用することができますfindと直接ファイル名を使用します。

find . -type f -mtime +15 -exec <your command here> {} \; 

をは、ファイル名のプレースホルダです。

あなたは、プロセス置換を使用して、一時ファイルを使用せずにこれを行うことができます
+0

問題は私が1つのコマンドを実行していないということです。私はすべてのタイプの奇妙な組み合わせを試してみることになります.exec後に引用符で囲み、エスケープする正しい方法を見つけてください。 – agnul

6

while read F 
do 
    ... 
done < <(find . -type f -mtime +15) 
+0

ニート!プロセスの置換について知らなかった。 – agnul

+1

プロセス置換機能はbash拡張機能であり、sh互換モードではbashで利用できないことに注意してください。それを動作させるには、スクリプトを '#!/ bin/bash'で起動する必要があります。ところで、ファイル名の先頭や末尾の空白や末尾のバックスラッシュを避けるために 'while IFS =" "read -r F'を使うことをお勧めします(ただし、ファイルがWindowsから来ていればバックスラッシュは可能)。 –

1

あなたのfindコマンドがまっすぐしばらくのあなたが知っているループ

find . -type f -mtime +15 | while read -r line 
do 
    printf "do something with $line\n" 
done 
関連する問題