以下のように、forループを使用して関数にパラメータを渡してファイルを1つずつ読み取ろうとします。パラメータ3はファイル名にスペースがあるため、多くの問題を引き起こす可能性があります。
例:
source_file_restructure()
{
echo "inside the function"
source_folder=$1
target_folder=$2
file_pattern=$3
delimiter=$4
echo $file_pattern
echo " Getting inside the function.... "
for file_name in `ls -Al ${source_folder}*"${file_pattern}"*.csv`
do
some processing.......
done
上記のlsコマンドは、ファイルにスペースが含まれている場合(ファイル1.csvなど)、正しく機能しません。
入力する:
SOurce Folder : /home/test/
File Pattern : "file"
Function argument :
source_file_restructure ${source_folder} ${target_folder} "${file_pattern}" ${delimiter}
この問題を解決するためのいくつかのオプションを提案してください。
答え1
変える
for file_name in `ls -Al ${source_folder}*"${file_pattern}"*.csv`
そして:
for file_name in "${source_folder}"*"${file_pattern}"*.csv
上記の最初の形式のように、逆引用符内のコマンド出力は単語の分離の影響を受けます。上記の2番目の形式はバックティックを使用しません。一方、スペース、タブ、改行、その他の難しい文字を含むファイル名など、すべてのファイル名を処理できます。
また、交換
source_file_restructure ${source_folder} ${target_folder} "${file_pattern}" ${delimiter}
そして
source_file_restructure "${source_folder}" "${target_folder}" "${file_pattern}" "${delimiter}"
二重引用符がない場合、シェルは単語の分離を実行します。二重引用符を使用すると、スペース、タブ、改行、その他の難しい文字があっても関数がsource_folder
正しく呼び出されます。target_folder
答え2
最初のスクリプトで次の環境変数を設定する必要があります。
IFS=$(echo -en "\n\b")
答え3
私のスクリプトの1つでは、次のようなものを使用しています。
ls -Q "$folderToRead" | while read file # ls -Q puts every entry between quotes : "file".
do
file=`echo $file | tr -d '"'` # This erases the quotes from the -Q argument, so you
# can work on the file without worrying about it.
もちろん、スクリプトで実行するにはlsコマンドを編集する必要があります。ちょうど短いバージョンで書いた。