![我们如何在 shell 脚本中的单个 for 循环中使用多个变量?](https://linux22.com/image/7009/%E6%88%91%E4%BB%AC%E5%A6%82%E4%BD%95%E5%9C%A8%20shell%20%E8%84%9A%E6%9C%AC%E4%B8%AD%E7%9A%84%E5%8D%95%E4%B8%AA%20for%20%E5%BE%AA%E7%8E%AF%E4%B8%AD%E4%BD%BF%E7%94%A8%E5%A4%9A%E4%B8%AA%E5%8F%98%E9%87%8F%EF%BC%9F.png)
我使用 for 循环实现如下代码,但运行脚本后输出错误。
for i in `awk -F"|" '{print $1}' $INPUTFILE`, j in `awk -F"|" '{print $2}' $INPUTFILE`
do
echo $i:$j
done
请帮助我在 shell 脚本中的单个 for 循环中使用多个变量。
答案1
bash 允许使用多个变量的 for 循环,但仅限于类似 C 的语法:
for ((i=0,j=10;i<=j;i++,j--))
do
echo "i=$i"
echo "j=$j"
done
答案2
也许你实际上想要:
while IFS='|' read -r i j rest <&3; do
{
printf '%s\n' "something with $i and $j"
} 3<&-
done 3< "$INPUTFILE"
在这里,听起来您只需要:
awk -F '|' '{print $1 ":" $2}' < "$INPUTFILE"
现在作为标题中问题的答案,对于for
带有多个变量的循环的 shell,您已经得到了zsh
(您似乎已经在使用 zsh 语法,不引用变量或在分割命令替换时不禁用通配符):
$ for i j in {1..6}; do echo $i:$j; done
1:2
3:4
5:6
或者更短的形式:
for i j ({1..6}) echo $i:$j
与 POSIX shell 等效:
set -- 1 2 3 4 5 6
## or:
# IFS='
# ' # split on newline
# set -o noglob # disable globbing
# set -- $(awk ...) # split the output of awk or other command
while [ "$#" -gt 0 ]; do
printf '%s\n' "$1:$2"
shift 2
done
答案3
您可以将文件的输出存储在变量中,然后将其分成两部分。例子:
在例子文件内容为:
a:1
b:2
c:3
d:4
现在脚本。
#!/bin/bash
for n in $(cat example)
do
first=$(echo $n | cut -d ":" -f 1)
second=$(echo $n | cut -d ":" -f 2)
echo $first
echo $second
done
答案4
在嵌入式系统上,您经常会因可用的内容而陷入困境。例如。for
只能有一个变量;awk
&printf
根本不可用;或IFS
不受支持; ETC。
在这些情况下,您可以这样实现您的目标:
export i=xxx
for j in `cat INPUTFILE` ; do \
[ $i == xxx ] && export i=$j && continue ; \
echo "$i:$j" ; \
export i=xxx ; \
done
unset i
该解决方案的更一般形式可能如下所示:
export A=xxx
export B=xxx
for i in 1 2 3 4 5 6 7 8 9 10 11 ; do \
[ $A == xxx ] && export A=$i && continue ; \
[ $B == xxx ] && export B=$i && continue ; \
echo "$A:$B:$i" ; \
export A=xxx ; \
export B=xxx ; \
done
unset A
unset B
- 假设字符串“xxx”从未出现在您的数据集中...如果出现/可能出现,请选择其他内容。
- 每个“记录”可以有任意数量的“字段”...只需复制处理字段 {A,B,...} 的四行中的每一行。
- 最后一个字段始终称为 $i ...如果有帮助,请随意
export C=$i
在之前添加一个。echo
- 如果数据集中的字符串数量不是记录大小的倍数,则“余数”(即 |set| % |record|)将丢失。