2014-02-19 24 views
1

我解析avahi浏览工具的输出,我的脚本应该是POSIX兼容的。POSIX shell中的换行符

我做下一方式:

 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线。有没有可能以更好的方式取代它?

我试图从计算器一些建议,但它不工作:

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

的avahi浏览的输出:

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

我想你可以使用'IFS = $'\ n'' – fedorqui

+0

fedorqui,我不能使用任何bashism。它将在POSIX shell上执行。 – Jurasic

+2

'本地'也不是POSIX shell的一部分。 – chepner

回答

3

IFS可变\n后添加一个空格,然后删除再次空间:

IFS="$(printf '\n ')" && IFS="${IFS% }" 
#IFS="$(printf '\n ')" && IFS="${IFS%?}" 
printf '%s' "$IFS" | od -A n -c 
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 
} 

在这两种情况下,在管道的右侧设置的任何变量是局部的外壳。如果您需要设置变量供以后使用,则需要进一步调整。

+0

如果字段可能有空格,如=; eth0; IPv4; \ 039s \ 032remote \ 032desktop \ 032on \ 032O; VNC远程访问;本地; O.local; 192.168 .26.19; 5900。 IFS =“;”后将无法检测整个领域。 – Jurasic

+1

通过将“IFS”设置为分号,空格被视为字段的一部分,而不是字段分隔符。 – chepner

0

如果能依靠其IFS具有它的默认值(空格,制表,换行)然后可以简单地剥离的前两个字符(空格和制表)和新行字符将保持:

IFS=${IFS#??} 
相关问题