2012-08-24 61 views
4

我想要執行一個從文件讀入參數的命令。 這工作正常,直到1的參數需要有一個空間。使用帶空格的文件的參數在bash腳本中調用函數

我試過用引號和反斜槓分組,但都沒有工作。

我以後的功能正是xargs呢,除了我需要調用一個函數,而不是一個命令,因爲它依賴於腳本

腳本設置了其他地方的變量:

do_echo() { 
    echo '$1:' $1 
    echo '$2:' $2 
} 
line=`cat input.txt` #cat used for simplicity, can have more than 1 line 
do_echo $line 

input.txt中:

"hello world" "hello back" 

預期結果:

$1: hello world 
$2: hello back 

觀測結果:

$1: "hello 
$2: world" 

編輯:

我用這多次與不同的輸入執行相同的命令。 每行最多有15個參數,可能超過50行。

表格格式將是理想的,儘管將每個參數放在一行上的當前答案將起作用。

+0

是否使用'do_echo「$ line」'提供了不同於'do_echo $ line'的結果? – twalberg

+0

@twalberg是的,它打印整個行作爲第一個參數,$ 1 –

回答

4

未加引號的變量(如do_echo $line)嚴格按IFS變量(默認設置爲製表符,空格,換行符)中的任何字符進行分割。嚴格意義是非常嚴格的,沒有辦法引用或逃避分裂。

基本的解決方法是將另外不需要的字符(例如冒號:)定義爲拆分字符。

例如

$ cat input.txt 
hello world:hello back 
$ line=$(head -n 1 input.txt) 
$ OLDIFS=$IFS IFS=: 
$ do_echo $line 
$1: hello world 
$2: hello back 
$ IFS=$OLDIFS 

另一個解決方法是使用evaleval是危險的。你絕對必須相信輸入!

$ cat input.txt 
"hello world" "hello back" 
$ line=$(head -n 1 input.txt) 
$ eval do_echo "$line" 
$1: hello world 
$2: hello back 
+0

謝謝。輸入在執行前經過驗證,並且eval是一個很好的快速解決方案 –

3

不使用引號,而是使用保證 不會出現在單個參數中的字符來分隔每個參數。例如,使用分號:

hello world;hello back 
argument 1;argument 2 

然後,可以讀取一組的參數,一個批次的時間,使用read

while IFS=';' read -a arguments; do 
    do_echo "${arguments[@]}" 
done < input.txt 

晦澀ASCII控制字符,像單元分隔符(ASCII 0x1f),如果可以將它們輸入到文件中,則不太可能出現在參數中。

+0

謝謝,我實際上使用它來執行多次不同輸入的命令。我想我可以用一行空白分隔參數組,但如果我可以將它們全部放在一行上,會更好。 –

+0

你能用除了換行符(逗號,分號等)來分隔參數嗎?解析從文件讀取的引用參數將會很棘手。 – chepner

+0

我可以。這些空格是由第三方提供的只讀文件名:(但是我可以控制其他所有內容 –

相關問題