シェルスクリプトで「ファイル」と「ディレクトリ名をスペースで分割」する

シェルスクリプトで「ファイル」と「ディレクトリ名をスペースで分割」する

Files.txt次の内容を持つというファイルがあります:

TestApp/Resources/Supporting Files/main.m
TestApp/Resources/Supporting Files/AppDelegate.h
TestApp/Resources/Supporting Files/AppDelegate.m

次のようにファイル名とディレクトリ名を取得し、別のプロセスに渡しています。

files=$(cat Files.txt)

for item in $files ; do    
  dn=$(dirname $item)

  printf $item
  printf "\n"
  printf $dn
  printf "\n\n"

  # passing to another process
done

しかし、これにより次のようになります:

TestApp/Resources/Supporting
TestApp/Resources

Files/main.m
Files

TestApp/Resources/Supporting
TestApp/Resources

Files/AppDelegate.h
Files

TestApp/Resources/Supporting
TestApp/Resources

Files/AppDelegate.m
Files

必要なのは次のものです:

TestApp/Resources/Supporting Files/main.m
TestApp/Resources/Supporting Files

TestApp/Resources/Supporting Files/AppDelegate.h
TestApp/Resources/Supporting Files

TestApp/Resources/Supporting Files/AppDelegate.m
TestApp/Resources/Supporting Files

次のように、スペースの前に\inを付けてみましたFiles.txt

TestApp/Resources/Supporting\ Files/main.m

そして%20次のようにします:

TestApp/Resources/Supporting%20Files/main.m

運が悪かった!

答え1

  1. forループは繰り返し言葉線ではない
  2. 常に引用符を付けてください"$variables"(引用符を付けてはいけない場合を除いて)
while read -r item ; do    
  dn=$(dirname "$item")

  printf "%s\n" "$item"
  printf "%s\n" "$dn"

  # pass "$item" and "$dn" to another process
done < Files.txt

答え2

フィールドセパレーターを設定する必要があります:

OIFS=$IFS  
IFS=$'\n'

files=$(cat Files.txt)

for item in $files ; do    
  dn=$(dirname $item)
  printf $item
  printf "\n"
  printf $dn
  printf "\n\n"

  # passing to another process
done

IFS=$OIFS

出力:

[me@localhost test]$ ./test.sh 
TestApp/Resources/Supporting Files/main.m
TestApp/Resources/Supporting Files

TestApp/Resources/Supporting Files/AppDelegate.h
TestApp/Resources/Supporting Files

TestApp/Resources/Supporting Files/AppDelegate.m
TestApp/Resources/Supporting Files

説明: http://en.wikipedia.org/wiki/内部フィールドセパレータ

変数$IFSは入力をトークンに分割する方法を定義します。デフォルトはスペース、タブ、改行です。改行のみで分割したいので、$IFS変数を一時的に変更する必要があります。

関連情報