2014-07-01 49 views
0

我已經編寫了一個腳本來將一些大的平面文件,子集的整數數量(即$增量)作爲用戶輸入變量。我只觀察奇怪的行爲(bash語法錯誤),只有當這個輸入參數是一個整數奇數。爲了(稍微)提高清晰度的目的,我在原始shell腳本的精簡版中複製了這種錯誤行爲。我無法提供平面文件,但希望有人使用shell/bash專業知識可以通過查看代碼和錯誤消息來診斷這裏發生的事情(我已經通過http://www.shellcheck.net/運行過,並且沒有發現任何嚴重問題)。bash算術表達式中的語法錯誤不一致:(錯誤標記爲「integer1-integer2」)

當$ increment設置爲一個偶數整數(例如8)時,shell腳本執行時沒有錯誤,併爲while循環的每次迭代輸出所需的打印語句(參見下面的「注意」)。下面是從那些打印語句的一些示例輸出:

Line of interest: span2=84688 
Line of interest: span2=85225 
Line of interest: span2=86323 
... 

當$增量然而奇數(例如9),該腳本在與線48 「跨距2 = $(($ $ line2- last2))」 失敗錯誤說法:

test_case.sh: line 48: 153026 
153027-77419: syntax error in expression (error token is "153027-77419") 

這很奇怪,因爲在前回波print語句輸出「利益線:跨度2 = 75278」表示該算術表達式在子shell評估沒有錯誤,只是失敗行之前。所以顯然沒有什麼特別的關於在這裏被減去的整數,但是奇怪的是,例如,當表達式參數$ line2等於「0」時,當它輸出「153026」時,錯誤消息看起來是錯開的。 153027" 。不過,我不確定這是否與語法錯誤有關。

#!/bin/bash 
set -e 


increment=9 
file1="path/to/file1" 
file2="path/to/file2" 
file3="path/to/file3" 

# End index of header in first file 
file1_start=2138 
midpoint=$(($file1_start + 1)) 

file1_wc=($(wc $file1)) 
file2_wc=($(wc $file2)) 
file3_wc=($(wc $file3)) 

# Get a line count for the three different flat text files, as an upper bound index 
ceil1=${file1_wc[0]} 
ceil2=${file2_wc[0]} 
ceil3=${file3_wc[0]} 

# Initialize end point indices 
line="$(head -$midpoint $file1 | tail -1 | awk '{print $1;}')" 
line2=$(grep -n -e "$line" $file2 | cut -f1 -d:) 
line3=$(grep -n -e "$line" $file3 | cut -f1 -d:) 

# Initialize starting point indices 
last1=$midpoint 
last2=$line2 
last3=$line3 

# Update "midpoint" index 
midpoint=$(($midpoint+$ceil1/$increment)) 

while [ $midpoint -lt $ceil1 ] 
do 

line="$(head -$midpoint $file1 | tail -1 | awk '{print $1;}')" 
line2=$(grep -n -e "$line" $file2 | cut -f1 -d:) 
line3=$(grep -n -e "$line" $file3 | cut -f1 -d:) 

# Calculate range of indices for subset number $increment 
span1=$(($midpoint-$last1)) 

echo "Line of interest: span2=$(($line2-$last2))" 
# ***NOTE***: The below statement is where it is failing for odd $increment 
span2=$(($line2-$last2)) 

span3=$(($line3-$last3)) 

# Set index variables for next iteration of file traversal 
index=$(($index+1)) 
last1=$midpoint 
last2=$line2 
last3=$line3 

# Increment midpoint index variable 
midpoint=$(($midpoint+$ceil1/$increment)) 

done 

您的反饋非常感謝,在此先感謝。


UPDATE:通過添加 「設置-x」 看着調用堆棧,我判斷爲表達

line2=$(grep -n -e "$line" $file2 | cut -f1 -d:) 

被greping多於一個的線。因此,在上面提供的示例中,$ line2等於「153026 \ n153027」,並且不是用於減法的聲音參數,因此是語法錯誤。解決這個問題的一種方法是管道到頭,例如,

line2=$(grep -n -e "$line" $file2 | cut -f1 -d: | head -1) 

只考慮grep產生的第一行。

+2

您是否曾嘗試在腳本中放置'set -x',以便您可以觀察其執行?這是調試shell腳本的常用方法。 – Barmar

+1

檢查壞行中的非打印字符 – Barmar

+0

確保使用bash運行它:'bash your_script.sh'。你可以展示你的bash版本嗎?'bash --version' – konsolebox

回答

2

ncemami:通過添加「設置-x」看着調用堆棧,我判斷爲表達

line2=$(grep -n -e "$line" $file2 | cut -f1 -d:) 

被greping多於一個的線。因此,在上面提供的示例中,$ line2等於「153026 \ n153027」,並且不是用於減法的聲音參數,因此是語法錯誤。解決這個問題的一種方法是管道到頭,例如,

line2=$(grep -n -e "$line" $file2 | cut -f1 -d: | head -1) 

只考慮grep產生的第一行。

+0

謝謝!你的回答讓我意識到,我的一個價值觀包含了一個額外的空間,不適合比較。 – schmunk

相關問題