如何逐行打印两个变量

时间:2015-05-13 15:00:24

标签: bash shell

我正在寻找一种在shell上逐行打印的方法。

例如,我有以下变量A和B,其中包含:

| A | B | 
| a | d | 
| b | c | 
| c | b | 
| d | a | 

我想要的输出是:

a d
b c
c b
d a

我试过了

awk 'BEGIN {OFS=" "}{
  getline line < "$A"
  print $0,line
} ' "$B"

但这不起作用。
A和B是多线字符串。例如A是* \ n b \ n c \ n d \ n *
请不要'列'或'粘贴'方法。

3 个答案:

答案 0 :(得分:1)

尝试使用此命令:

while read -u7 a && read -u8 b; do echo "[$a] [$b]"; done 7<<<"$A" 8<<<"$B" 

while read -u7 a && read -u8 b; do echo "[$a] [$b]"; done \
    7< <(echo "$A") 8< <(echo "$B") 

此处read -u7 a表示从文件描述符7读入a变量, 7<<<"$A"表示将$A的内容重定向到文件描述符7, 和7< <(echo "$A")表示将echo输出重定向到文件描述符7.

例如,如果我有A=$(seq 10 15); B=$(seq 20 25);,则结果为:

[10] [20]
[11] [21]
[12] [22]
[13] [23]
[14] [24]
[15] [25]

答案 1 :(得分:1)

我认为你不想使用paste的原因是你想进一步处理价值对。

如果在 shell 代码中执行此处理就足够了,请考虑tivn's helpful answerCharles Duffy's helpful answer

如果您确实希望使用awk进行进一步处理,请参阅解决方案尝试,请考虑 pasteawk合并:

#!/usr/bin/env bash

# Sample input
A=$'a\nb\nc\nd'
B=$'d\nc\nb\na'

paste <(echo "$A") <(echo "$B") | awk '{ print "Pair #" NR ": ", $1, $2 }'
  • paste <(echo "$A") <(echo "$B")合并来自两个输入变量的相应行,原点行由\t实例分隔。
  • awk的默认字段拆分会为每个输入行提供相应的值$1$2字段。

至于为什么awk命令不起作用

awk 'BEGIN {OFS=" "}{
  getline line < "$A"
  print $0,line
} ' "$B"
  • 您的awk脚本是单引号,但您似乎在尝试引用 shell 变量$A

    • 由于shell不解释单引号字符串,因此awk将解释$A,这不是意图;
      一般来说,尽管使用单引号字符串是良好的做法,但要避免在shell提前扩展和awk看到的内容之间产生混淆;使用-v varName=varValue选项将shell变量值传递给awk
    • awk然后使用 awk 变量$A中存储的索引解释$ _field(A) - 因为变量{{1} }未定义,它等效于A,当前输入行(GNU awk,mawk)或运行时错误(BSD awk)。
    • 即使你设法使用 shell 变量$0"$A"方法也行不通,因为它需要文件名;因此,您必须先将getline line <的内容写入(临时)文件,然后$A中指定该文件的路径以代替$A } script。
    • 正如您所看到的,这很麻烦,而且通常awk很少是正确的做法 - 请参阅http://awk.info/?tip/getline
  • 此外,您传递getline,即使它包含数据,就好像它是{em>文件名到"$B"

    • 要真正传递数据,您必须使用 stdin ;在awk中,最简单的方法是使用bash(所谓的here-string)。

答案 2 :(得分:1)

将每个字符串的元素加载到数组中会使成对处理更容易。例如:

#!/bin/bash
#      ^- must be bash, not sh, for arrays to be a supported feature

IFS=$'\n' read -r -d '' -a array_a <<<"$A"
IFS=$'\n' read -r -d '' -a array_b <<<"$B"

for idx in "${!array_a[@]}"; do
  printf '%s\t|%s\n' "${array_a[$idx]}" "${array_b[$idx]}"
done