POSIX shell中的换行符

时间:2014-02-19 12:45:44

标签: shell unix scripting

我正在解析avahi-browse工具的输出,我的脚本应该与POSIX兼容。

我正在接下来这样做:

      local _dnssd=`avahi-browse -apt`
      if [ -z "$_dnssd" ]; then
        echo "No info"
      else
        IFS='
    ' # it's new line character in IFS
        for _row in $_dnssd
         do  
          local _tmpIFP="$IFS"
          IFS=";"
            case "$_row" in
            ...
            esac
            IFS="$_tmpIFS"
        done
      fi  

我真的不喜欢与IFS分配换行符。是否有可能以更好的方式更换它?

我尝试了stackoverflow的一些建议,但它不起作用:

IFS=$(echo -e '\n')

avahi-browse输出:

+;br0;IPv4;switch4B66E4;_http._tcp;local
+;br0;IPv4;switch4B66E4;_csco-sb._tcp;local

3 个答案:

答案 0 :(得分:3)

\n变量中的IFS之后添加空格,然后再次删除该空格:

IFS="$(printf '\n ')" && IFS="${IFS% }"
#IFS="$(printf '\n ')" && IFS="${IFS%?}"
printf '%s' "$IFS" | od -A n -c 

答案 1 :(得分:2)

使用while循环比尝试迭代包含整个输出的字符串更好。

avahi-browse -apt | while IFS=";" read field1 field2 ...; do
    case ... in
    ...
    esac
done

请注意,read命令的每个字段都需要一个名称。 ...只是一个占位符,不是有效数量字段的有效shell语法。

如果程序没有输出,这根本不起作用。如果您确实需要检测到这种情况,请尝试

avahi-browse -apt | {
    read line || { echo "No info"; exit; }
    while : ; do
        IFS=";" read field1 field2 ... <<EOF
        $line
EOF
        case ... in
        ...
        esac
        read line || break
    done
}

在这两种情况下,管道右侧设置的任何变量都是该shell的本地变量。如果您需要设置变量供以后使用,则需要进行进一步调整。

答案 2 :(得分:0)

如果可以依赖* IFS具有其默认值(空格,制表符,新行),则可以简单地删除前两个字符(空格和制表符),并保留新的行字符:

IFS=${IFS#??}

*如果IFS之前没有被IFS修改过,如果它是POSIX shell(如主题所暗示的那样),你可以依赖它:

  

shell应将IFS设置为&lt; space&gt;&lt; tab&gt;&lt; newline&gt;当它被调用时。

请参阅http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_05_03