bash算术表达式中的语法错误不一致:(错误标记为" integer1-integer2")

时间:2014-07-01 01:00:18

标签: bash shell

我编写了一个脚本来分配一些大的平面文件,其中整数个子集(即$ increment)作为用户输入变量。仅当此输入参数是奇数整数时,我才会观察到奇怪的行为(bash语法错误)。为了(略微)提高清晰度,我在原始shell脚本的精简版本中复制了此错误行为。我无法提供平面文件,但希望有shell / bash专业知识的人可以通过查看代码和错误消息来诊断这里发生了什么(我已经通过http://www.shellcheck.net/运行并且没有&# 39;找不到任何严重的问题。)

当$ increment设置为偶数(例如8)时,shell脚本执行无错误,并为while循环的每次迭代输出所需的打印语句(参见" NOTE"下面)。以下是这些打印语句的一些示例输出:

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

当$ increment为奇数时(例如9),脚本在第48行" span2 = $(($ line2- $ last2))"错误陈述:

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

这很奇怪,因为前面的echo print语句输出"感兴趣的行:span2 = 75278"表示算术表达式正在子shell中进行评估而没有错误,就在失败的行之前。显然,这里减去的整数没有什么特别之处,但奇怪的是,例如,当它输出" 153026"时,错误信息似乎是一个接一个的。当表达式参数$ line2等于" 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

非常感谢您的反馈,谢谢。


更新:通过添加"设置-x"并且看着调用堆栈,我确定了表达式

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

不止一条线。因此,在上面提供的示例中,$ line2等于" 153026 \ n153027",并且不是减法的声音参数,因此语法错误。解决这个问题的一种方法是管道,例如

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

只考虑grep产生的第一行。

1 个答案:

答案 0 :(得分:2)

ncemami:通过添加“set -x”并查看调用堆栈,我确定了表达式

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

不止一条线。因此,在上面提供的示例中,$ line2等于“153026 \ n153027”,并且不是减法的声音参数,因此语法错误。解决这个问题的一种方法是管道,例如

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

只考虑grep产生的第一行。