我正在解析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
答案 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