在bash中将每一行读作参数

时间:2014-04-25 01:46:34

标签: bash shell scripting compilation command

我正在努力学习抨击。我正在尝试运行./test testcase 测试用例中的文件在下一行有参数9 11 22 13,32 35 32 16,依此类推 我的程序需要4个参数。现在如果testcase有一行参数,即3 5 6 7它可以正常工作,但是当有超过2时它无法正常运行程序。我知道我需要一个while循环来读取文件的每一行,但我被困在这里。如果有人能帮助我,我将不胜感激。先感谢您。 我之前在这里问过这个问题,我不知道每个人是否太忙或者不知道怎么做。再次感谢

your_path=../test/test
test_path=../../public/test    
file_input="$1"
#while read -r line; do
#done < "$file_input"

# Read contents in the file
contents=$(< "$file_input")
# Display output of the test file
"$test_path" $contents > correctanswer 2>&1
# Display output of your file
"$your_path" $contents > youranswer 2>&1
diff the solutions
diff correctanswer youranswer > /dev/null 2>&1
if [ $? -eq 0 ]
then
  echo "The two outputs were exactly the same "
else
  echo "$divider"
  echo "The two outputs were different "
  diff youranswer correctanswer
  echo "Do you wish to see the ouputs side-by-side?"
      select yn in "Yes" "No"; do
      case $yn in
         Yes ) echo "LEFT: Your Output   RIGHT: Solution Output"
               sleep 1
               vimdiff youranswer correctanswer; break;;
         No ) exit;;
      esac
      done
fi

2 个答案:

答案 0 :(得分:1)

我通常会使用类似于以下的构造(适用于您的示例)。请注意,您需要进行的唯一更改是关闭周期的cat $file | (while read l; do然后done)。循环体正好是您的代码,但contents替换为l(行读取)。围绕循环的括号实际上启动了shell的另一个实例,其中while执行并且stdin设置为从cat传送。

your_path=../test/test
test_path=../../public/test    
file_input="$1"

exec 3< $file_input
while read -u 3 l; do
# do your per-test diffs and outputs here
# variable $l will contain one line of $file_input
    # Display output of the test file
    "$test_path" $l > correctanswer 2>&1
    # Display output of your file
    "$your_path" $l > youranswer 2>&1
    # diff the solutions
    diff correctanswer youranswer > /dev/null 2>&1
    if [ $? -eq 0 ]
    then
      echo "The two outputs were exactly the same "
    else
      echo "$divider"
      echo "The two outputs were different "
      diff youranswer correctanswer
      echo "Do you wish to see the ouputs side-by-side?"
          select yn in "Yes" "No"; do
          case $yn in
             Yes ) echo "LEFT: Your Output   RIGHT: Solution Output"
                   sleep 1
                   vimdiff youranswer correctanswer; break;;
             No ) exit;;
          esac
          done
    fi

done

答案 1 :(得分:0)

我认为你可以这样做:

your_path=../test/test
test_path=../../public/test    
file_input="$1"
while read -r -u 3 contents
do
    # Display output of the test file
    "$test_path" $contents > correctanswer 2>&1
    # Display output of your file
    "$your_path" $contents > youranswer 2>&1
    # diff the solutions
    diff correctanswer youranswer > /dev/null 2>&1
    if [ $? -eq 0 ]
    then
        echo "The two outputs were exactly the same "
    else
        echo "$divider"
        echo "The two outputs were different "
        diff youranswer correctanswer
        echo "Do you wish to see the ouputs side-by-side?"
        select yn in "Yes" "No"; do
            case $yn in
                Yes)  echo "LEFT: Your Output   RIGHT: Solution Output"
                      sleep 1
                      vimdiff youranswer correctanswer
                      break;;
                 No)  exit;;
            esac
        done
    fi
done 3< "$file_input"

修改,以便read命令读取文件描述符3,保留标准输入可用于select等。


我不知道你在做什么导致它失败。我创建了两个程序test1test2。最初,它们完全相同:

printf "%s\n" "$@"

然后我改变了test2所以它包含:

printf "%s\n" "1$@2"

将此数据放在input.file

9 11 22 13
2 35 32 16

我运行了脚本botched.sh

$ bash -x botched.sh input.file
+ '[' -f /etc/bashrc ']'
+ . /etc/bashrc
++ '[' -z '' ']'
++ return
+ alias 'r=fc -e -'
+ your_path=./test1
+ test_path=./test2
+ file_input=input.file
+ read -r -u 3 contents
+ ./test2 9 11 22 13
+ ./test1 9 11 22 13
+ diff correctanswer youranswer
+ '[' 0 -eq 0 ']'
+ echo 'The two outputs were exactly the same '
The two outputs were exactly the same 
+ read -r -u 3 contents
+ ./test2 2 35 32 16
+ ./test1 2 35 32 16
+ diff correctanswer youranswer
+ '[' 0 -eq 0 ']'
+ echo 'The two outputs were exactly the same '
The two outputs were exactly the same 
+ read -r -u 3 contents
$

输出被认为是相同的,正如您所期望的那样。然后使用修改后的test2,我重申了它:

$ bash -x botched.sh input.file
+ '[' -f /etc/bashrc ']'
+ . /etc/bashrc
++ '[' -z '' ']'
++ return
+ alias 'r=fc -e -'
+ your_path=./test1
+ test_path=./test2
+ file_input=input.file
+ read -r -u 3 contents
+ ./test2 9 11 22 13
+ ./test1 9 11 22 13
+ diff correctanswer youranswer
+ '[' 1 -eq 0 ']'
+ echo ''

+ echo 'The two outputs were different '
The two outputs were different 
+ diff youranswer correctanswer
1c1
< 9
---
> 19
4c4
< 13
---
> 132
+ echo 'Do you wish to see the ouputs side-by-side?'
Do you wish to see the ouputs side-by-side?
+ select yn in '"Yes"' '"No"'
1) Yes
2) No
#? 1
+ case $yn in
+ echo 'LEFT: Your Output   RIGHT: Solution Output'
LEFT: Your Output   RIGHT: Solution Output
+ sleep 1
+ vimdiff youranswer correctanswer
2 files to edit
+ break
+ read -r -u 3 contents
+ ./test2 2 35 32 16
+ ./test1 2 35 32 16
+ diff correctanswer youranswer
+ '[' 1 -eq 0 ']'
+ echo ''

+ echo 'The two outputs were different '
The two outputs were different 
+ diff youranswer correctanswer
1c1
< 2
---
> 12
4c4
< 16
---
> 162
+ echo 'Do you wish to see the ouputs side-by-side?'
Do you wish to see the ouputs side-by-side?
+ select yn in '"Yes"' '"No"'
1) Yes
2) No
#? 2
+ case $yn in
+ exit
$

vimdiff程序确实运行并显示差异。

请注意基本调试技术 - 使用bash -x运行。它显示读取带有四个数字的单行输入,然后传递给代理程序test1test2;然后需要第二行,并将其传递给代理项目。

实际测试代码:

your_path=./test1 #../test/test
test_path=./test2 #../../public/test    
file_input="$1"
while read -r -u 3 contents
do
    # Display output of the test file
    "$test_path" $contents > correctanswer 2>&1
    # Display output of your file
    "$your_path" $contents > youranswer 2>&1
    # diff the solutions
    diff correctanswer youranswer > /dev/null 2>&1
    if [ $? -eq 0 ]
    then
        echo "The two outputs were exactly the same "
    else
        echo "$divider"
        echo "The two outputs were different "
        diff youranswer correctanswer
        echo "Do you wish to see the ouputs side-by-side?"
        select yn in "Yes" "No"; do
            case $yn in
                Yes)  echo "LEFT: Your Output   RIGHT: Solution Output"
                      sleep 1
                      vimdiff youranswer correctanswer
                      break;;
                 No)  exit;;
            esac
        done
    fi
done 3< "$file_input"

在Mac OS X 10.9.2上使用Bash 3.2.51进行测试。

如果它不适合你,那么你需要设置代理测试程序,类似于我的,并显示你在脚本上运行bash -x得到的结果。您还应该识别正在运行的平台以及正在运行的Bash版本。