2014-10-26 95 views
0

我是bash的新手,我正在處理遍歷tar.gz文件存檔的腳本,並在每個文件中將指定的字符串更改爲另一個字符串。腳本的參數:存檔的名稱,搜索的字符串,目標詞。我有以下錯誤: 在線if [ ! -f $filename ] ; then [我的問題是,當存檔名稱包含空格(例如我運行具有以下參數腳本:> change_strings.sh「/tmp/tmp.m7xYn5EQ2y/work/data txt」a A)我有以下錯誤: 在線if [ ! -f $filename ] ; then [ :data:預期的二元運算符,dirname:額外的操作數'txt'。 這裏是我的代碼:目錄名稱Bash中的空格

#!/bin/bash 
    filename="${1##*/}" 
    VAR="$1" 
    DIR=$(dirname ${VAR}) 
    cd "$DIR" 


if [ ! -f $filename ] ; then 
echo "no such archive" >&2 
exit 1 
fi 


if ! tar tf $filename &> /dev/null; then 
echo "this is not .tar.gz archive" >&2 
exit 1 
fi 


dir=`mktemp -dt 'test.XXXXXX'` 
tar -xf $filename -C $dir #extract archive to dir 
cd $dir #go to argument directory 

FILES=$dir"/*" 

for f in $FILES 
do 
sed -i "s/$2/$3/g" "$f" 
done 

tar -czf $filename * #create tar gz archive with files in current directory 
mv -f $filename $cdir"/"$filename #move archive 
rm -r $dir #remove tmp directory 
+1

Crossposting:http://unix.stackexchange.com/q/164328/74329 – Cyrus 2014-10-26 15:47:10

回答

1

來處理這個正確的方法是用雙引號包圍你的變量。

var=/foo/bar baz 
CMD $var # CMD /foo/bar baz 

上面的代碼將上/富/ bar和baz

CMD "$var" 

這將在 「/富/酒吧baz」 的執行CMD執行CMD。在大多數地方總是用雙引號括住變量是一種最佳做法。

1

歡迎使用stackoverflow!

對於當前和未來的讀者的方便,這裏的顯示問題small, self contained example

filename="my file.txt" 
if [ ! -f $filename ] 
then 
    echo "file does not exist" 
fi 

下面是我們得到的輸出:

$ bash file 
file: line 2: [: my: binary operator expected 

下面是我們所期望得到的輸出:

file does not exist 

他們爲什麼不一樣?


這裏是shellcheck不得不說一下吧:

$ shellcheck file 
In file line 2: 
if [ -f $filename ] 
     ^-- SC2086: Double quote to prevent globbing and word splitting. 

而事實上,如果我們雙引號呢,我們得到的預期輸出:

$ cat file 
filename="my file.txt" 
if [ ! -f "$filename" ] 
then 
    echo "file does not exist" 
fi 

$ bash file 
file does not exist 

你應該double quoting all your variables

但是,您必須注意$FILES,因爲它包含您想要擴展的glob /通配符,以及您不想拼寫的潛在空格。最簡單的方法是隻不把它放在一個變量,而是寫出來:

for f in "$dir"/* 
do 
    ... 
相關問題