shell 脚本 - echo 命令未按正确顺序打印

Egg*_*ead 1 shell-script

我有以下几点testfile.txt

string1 1  
string2 2  
string3 3  
string1 2  
string2 4  
string3 6  
string1 3  
string2 6  
string3 9  
Run Code Online (Sandbox Code Playgroud)

我有以下脚本:

#!bin/sh

oldstr="abc"  
while read line  
do  
    newstr=\`echo "$line" | sed 's/\(.*\)\( \)\([0-9].*\)/\1/'\`
    echo "$oldstr vs $newstr"

    if [ $oldstr == $newstr ] 
    then 
       echo "old $oldstr"
    else
       oldstr=$newstr
       echo "new $oldstr"
    fi
done < $@ | sort
echo "done"
Run Code Online (Sandbox Code Playgroud)

然后我运行脚本:

$ sh test.sh testfile.txt
Run Code Online (Sandbox Code Playgroud)

并得到输出:

abc vs string1  
new string1  
new string1  
new string1  
new string2  
new string2  
new string2  
new string3  
new string3  
new string3  
string1 vs string2  
string1 vs string2  
string1 vs string2  
string2 vs string3  
string2 vs string3  
string2 vs string3  
string3 vs string1  
string3 vs string1  
done
Run Code Online (Sandbox Code Playgroud)

我想知道为什么,因为我希望输出是:

abc vs string1  
new string1  
string1 vs string1
old string1  
string1 vs string1
old string1  
string1 vs string2
new string2  
Run Code Online (Sandbox Code Playgroud)

等等。

  1. 为什么“if”语句不起作用?
  2. 为什么回声打印乱序?

Rma*_*ano 5

1)他们因为你的要求而失序:你准备了整个清单,然后| sort他们。

2)测试应该是(标准sh语法):(if [ "$variable" = ...不是==)。

3)测试事物,使用sh -xvwhich 将在执行之前打印每一行以及扩展的结果。

4)你为什么要逃避反引号?

5)你的变量周围缺少引号

6)< $@仅当脚本只有一个参数时才有效。

7) 在read没有-r和没有删除空格字符的情况下使用$IFS可能在这里没有意义。

8)你不能使用echo任意数据

9) 应该是#!/bin/sh,不是#!bin/sh

工作脚本:

#!/bin/sh 

oldstr="abc"  
while IFS= read -r line  
do  
    newstr=`printf '%s\n' "$line" | sed 's/\(.*\)\( \)\([0-9].*\)/\1/'`
    printf '%s\n' "$oldstr vs $newstr"

    if [ "$oldstr" = "$newstr" ] 
    then 
       echo "old $oldstr"
    else
       oldstr=$newstr
       printf '%s\n' "new $oldstr"
    fi
done < "$1" 

echo "done"
Run Code Online (Sandbox Code Playgroud)

此外,您应该更改输入测试文件。您发布的那个永远不会触发“旧”案例。

如果要在将文件传递给循环之前对其进行排序,请将while行更改为:

sort -- "$@" | while IFS= read -r line 
Run Code Online (Sandbox Code Playgroud)

并显然删除< $@之后done

sort -- "$@" | while IFS= read -r line  
do  
   [...]
done
Run Code Online (Sandbox Code Playgroud)