Bash
帶有包含空格的字元串 var 的 Bash for 循環
在我的目錄中,我有兩個帶空格的文件,
foo bar
和another file
. 我也有兩個沒有空格的文件,file1
和file2
.以下腳本有效:
for f in foo\ bar another\ file; do file "$f"; done
此腳本也適用:
for f in 'foo bar' 'another file'; do file "$f"; done
但以下腳本不起作用:
files="foo\ bar another\ file" for f in $files; do file "$f"; done
甚至這個腳本也不起作用:
files="'foo bar' 'another file'" for f in $files; do file "$f"; done
但是,如果文件不包含空格,則腳本可以工作:
files="file1 file2" for f in $files; do file "$f"; done
謝謝!
編輯
我的腳本的程式碼片段:
while getopts "i:a:c:d:f:g:h" arg; do case $arg in i) files=$OPTARG;; # ... esac done for f in $files; do file "$f"; done
對於沒有空格的文件,我的腳本可以工作。但我想以下列方式之一執行以空格作為參數傳遞文件的腳本:
./script.sh -i "foo\ bar another\ file" ./script.sh -i foo\ bar another\ file ./script.sh -i "'foo bar' 'another file'" ./script.sh -i 'foo bar' 'another file'
對於您的命令行解析,將路徑名操作數安排為始終是命令行上的最後一個:
./myscript -a -b -c -- 'foo bar' 'another file' file[12]
選項的解析看起來像
while getopts abc opt; do case $opt in a) a_opt=true ;; b) b_opt=true ;; c) c_opt=true ;; *) echo error >&2; exit 1 esac done shift "$(( OPTIND - 1 ))" for pathname do # process pathname operand "$pathname" here done
這
shift
將確保關閉已處理的選項,以便路徑名操作數是位置參數列表中唯一剩下的東西。如果這不可能,請允許
-i
多次指定該選項,並在每次在循環中遇到它時將給定的參數收集在一個數組中:pathnames=() while getopts abci: opt; do case $opt in a) a_opt=true ;; b) b_opt=true ;; c) c_opt=true ;; i) pathnames+=( "$OPTARG" ) ;; *) echo error >&2; exit 1 esac done shift "$(( OPTIND - 1 ))" for pathname in "${pathnames[@]}"; do # process pathname argument "$pathname" here done
這將被稱為
./myscript -a -b -c -i 'foo bar' -i 'another file' -i file1 -i file2
如果您正在使用
bash
,您可以為此使用數組#!/bin/bash files=('foo bar' 'another file' file1 'file2') for f in "${files[@]}"; do file -- "$f"; done
包含空格的文件名需要引號;對於純文件名,它是可選的(但我推薦它)。如果文件列表來自目前目錄,您可以使用萬用字元,例如
files=(*f*)
匹配f
名稱中的任何文件或目錄。(但是您可能只使用for f in *f*; do...done
並完全避免使用該數組。)--
for 的標記file
告訴它任何後續參數都是文件名 - 即使它以破折號開頭。
man bash
使用(搜尋)了解更多資訊Arrays
。