web-dev-qa-db-ja.com

bashのファイルからファイル名のリストを読み取るにはどうすればよいですか?

入力ファイルに1行に1つずつ名前が保存されているファイルのリストを処理するbashスクリプトを作成しようとしています。

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

私の問題は、filelist.txtのファイル名にスペースが含まれている可能性があるため、上記のように切り取られた行が展開されることです。

my text file.txt

3つの異なるファイル名、mytextおよびfile.txt。どうすれば修正できますか?

31
agnul

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オプションを使用して、各ファイルが直接見つかった場合に実行します。

41
Douglas Leeder

プロセス置換を使用して、一時ファイルなしでこれを行うことができます。

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

読みながら使用する

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

エコーの代わりにリダイレクトを行うことができます

3
DVK

find-execパラメーターを使用し、ファイル名を直接使用できます。

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

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

2
tangens

findコマンドをwhile readループに直接パイプする

find . -type f -mtime +15 | while read -r line
do
   printf "do something with $line\n"
done
1
ghostdog74

私は決してbashの専門家ではありません(通常、スクリプトをRubyまたはpythonクロスプラットフォームにする)で記述しますが、処理する前に各行のスペースをエスケープする正規表現のエクスプレッション。

Bash Regexの場合: http://www.linuxjournal.com/node/1006996

同様の状況でRuby(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  
0
konung