在bash中循环使用多对值

Ris*_*ish 16 bash for-loop paste nested-loops

我有10个文本文件,我希望paste每个文件都有一对,这样我就有5个文件.

我尝试了以下方法:

for i in 4_1 5_1 6_1 7_1 8_1
do
for j in 4_2 5_2 6_2 7_2 8_2
do
paste ${i}.txt ${j}.txt > ${i}.${j}.txt
done
done
Run Code Online (Sandbox Code Playgroud)

但是,此代码组合了所有可能的组合,而不是仅仅组合匹配对.

所以我想文件4_1.txt与配对4_2.txt,5_1.txt5_2.txt

Cha*_*ffy 27

我同意fedorqui目前在问题背景下提出的答案.以下仅提供一些更一般的答案.

另一种通用方法(对于bash 4.0或更新版本)是将对存储在关联数组中:

declare -A pairs=( [4_1]=4_2 [5_1]=5_2 [6_1]=6_2 [7_1]=7_2 [8_1]=8_2 )
for i in "${!pairs[@]}"; do
  j=${pairs[$i]}
  paste "$i.txt" "$j.txt" >"${i}.${j}.txt"
done
Run Code Online (Sandbox Code Playgroud)

另一个(与旧版本的bash兼容)是使用多个传统阵列:

is=( 4_1 5_1 6_1 7_1 8_1 )
js=( 4_2 5_2 6_2 7_2 8_2 )
for idx in "${!is[@]}"; do
  i=${is[$idx]}
  j=${js[$idx]}
  paste "$i.txt" "$j.txt" >"$i.$j.txt"
done
Run Code Online (Sandbox Code Playgroud)

  • @CharlesDuffy我来这里是因为我在Google中输入了“[iterate inpairs bash](https://www.google.com/search?q=iterate+in+pairs+bash)”,而不是因为我关心OP的问题。 (4认同)

Fib*_*sky 12

迄今为止最简单的:

for i in "1 a" "2 b" "3 c"; do a=( $i ); echo "${a[1]}"; echo "${a[0]}"; done

a
1
b
2
c
3
Run Code Online (Sandbox Code Playgroud)

  • 为什么这被否决了?它适用于 bash ver.3 及更高版本,并且足够简单,不需要使用heredoc。 (2认同)
  • 比其他解决方案更好的解决方案 (2认同)
  • 简单而且效果很好,谢谢。 (2认同)

fed*_*qui 9

如果你想使用一个变量并使用它执行和操作,你只需要使用一个循环:

for file in 4 5 6 7 8
do
   paste "${file}_1" "${file}_2"
done
Run Code Online (Sandbox Code Playgroud)

这样做

paste 4_1 4_2
paste 5_1 5_2
...
Run Code Online (Sandbox Code Playgroud)

  • 看,马!没有循环:`printf'%s%s \n'{4..8} _ {1,2} | xargs -I cmd粘贴cmd` (4认同)
  • 但是如果你有一些需要引用或转义的重要文件名,那么在未加引号的值上运行`xargs`会很快累积起来. (2认同)

Vas*_*kov 8

您可以使用关联数组:

animals=(dog cat mouse)
declare -A size=(
  [dog]=big
  [cat]=medium
  [mouse]=small
)
declare -A sound=(
  [dog]=barks
  [cat]=purrs
  [mouse]=cheeps
)
for animal in "${animals[@]}"; do
  echo "$animal is ${size[$animal]} and it ${sound[$animal]}"
done
Run Code Online (Sandbox Code Playgroud)

这允许你遍历对,三元组等.积分:最初的想法来自@ CharlesDuffy的回答.

  • 难道我没有建议(并演示)这种技术 - 在适合OP问题的上下文中,围绕“粘贴”的调用 - [早在2015年](/sf/answers/2010789371/) ? (2认同)

spl*_*san 7

上面的内容对我不起作用,但以下内容确实从有序列表中成对读取值

(可以多对添加额外的“阅读行”:-)

while read x; do
  read y
  echo "$x $y"
done << '___HERE'
X1
Y1
X2
Y2
X3
Y3
___HERE
Run Code Online (Sandbox Code Playgroud)

产生

X1 Y1
X2 Y2
X3 Y3
Run Code Online (Sandbox Code Playgroud)

  • 您还可以 `while read x &amp;&amp; read y; do`,我发现这让读者更容易理解每​​次迭代消耗两个项目。 (3认同)