我写了
for pair in $(my command | sed -En "s/my expression/\1 \2/p"); do
echo $pair
done
但每行都有所有条目:
host
port
host
port
...
如果我打印
my command | sed -En "s/my expression/\1 \2/p"
我明白了
host port
host port
host port
...
如何正确准备值对?
答案 0 :(得分:2)
您正在使用命令替换而不是设置IFS,请尝试:
IFS='\n'
for pair in $(my command | sed -En "s/my expression/\1 \2/p"); do
echo $pair
done
默认设置是在空格,制表符和换行符之间进行分割。在这里,您只想在换行符上进行拆分,因此您需要将IFS设置为该值,否则意味着如果该对包含空格或制表符,将无法正常工作
答案 1 :(得分:1)
原因很简单,
for pair in $(…)
对空格(在您的情况下包括单个空格)进行迭代。一口气评估了$()
中的命令,这些结果为for
循环提供了结果,它只会看到您给它的参数列表。因此,在开始for
循环之前,请先设置IFS=$'\n'
。
IFS=$'\n'
for pair in $(…)
答案 2 :(得分:0)
如果这不是一个非常简单的替代词,我会尽量避免使用sed
。 awk
的能力更强,同时也更清晰。这是POSIX awk
的答案。
my command | awk '{ d="\n"; if (NR%2) d=" "; printf $0 d}'
但是,如果将间距放入command substitution($(…)
格式)中,将无法保留间距。要解决此问题,请考虑使用其他成对的定界符,例如将d=" "
更改为d=":"
for pair in "$(my command | awk '{ d="\n"; if (NR%2) d=":"; printf $0 d}')"; do
echo $pair
done
如果您实际上想对一对的不同部分做某事,请使用bash进行整个操作:
line_num=0
while IFS= read line; do
line_num=$((line_num+1))
if [ $((line_num%2)) = 1 ]; then
host="$line"
else
port="$line"
# do things with $host and $port here
echo "$host $port"
fi
done < <(my command)