Unix:将第二列的每个元素附加到第一列的每个元素

时间:2019-07-07 14:54:46

标签: bash unix cartesian-product

我不是经验丰富的程序员,因此无法找到以下解决方案。原谅我说的话不正确(这可能是我的搜索问题)

我有两个单列文件

A
B
C

X
Y
Z

我想创建一个文件,该文件将第二列的每个元素附加到第一列的每个元素上,以获取:

AX
AY
AZ
BX
BY
BZ
CX
CY
CZ

结果的顺序并不重要(例如AX,BX等)就可以了。

我看到的大多数示例都使用剪切和粘贴,但这仅提供了我正在寻找的部分解决方案。

我乐于接受任何方法,但如果可以在bash shell中进行操作,则我更愿意这样做。

非常感谢。

JPG

4 个答案:

答案 0 :(得分:1)

可以这样:

#!/usr/bin/env sh

file1='a.txt'
file2='b.txt'

array2="$(cat "${file2}")"

for i in $(cat "${file1}"); do
  for j in ${array2}; do
    echo "${i}${j}"
  done
done

答案 1 :(得分:0)

对于大文件,这可能会变慢,但这也可行:

cat file1.txt | xargs -d ' ' -I var sh -c 'for i in `cat file2.txt`; do echo var$i; done'
AX
AY
AZ
BX
BY
BZ
CX
CY
CZ

编辑 通过将第二个文件的内容首先写入变量

可能会更有效
SECOND_FILE=$(cat file2.txt) | cat file1.txt | xargs -d ' ' -I var sh -c 'for i in `echo $SECOND_FILE`; do echo var$i; done'

如果您想了解此命令和其他命令,我建议explain shell

答案 2 :(得分:0)

使用awk可以简单地做到这一点,方法是将每个文件中的值存储在一个数组中,然后利用嵌套的for循环集简单地输出值,例如

awk '
    FNR == NR {a[i++] = $1}
    FNR < NR {b[j++] = $1}
    END { 
        for (i in a)
            for (j in b)
                printf "%s%s\n", a[i], b[j] }
' file1 file2

该命令通过比较看到的FNR(文件记录号)和NR(记录总数)来工作。如果它们相等,则您正在读取第一个文件,并将行存储在数组a中。如果NR > FNR正在读取第二个文件,则将行存储在数组b中。 END中的,仅使用嵌套循环输出所需输出的数组。 (您可以在END的开头添加一个验证,例如if (i != j),以验证每个记录中的记录数是否相等)

鉴于显示为file1file2存储的两个文件将产生以下输出:

AX
AY
AZ
BX
BY
BZ
CX
CY
CZ

(您可以简单地选择awk命令,然后在鼠标中键将其粘贴到终端中进行测试,例如)

$ awk '
>     FNR == NR {a[i++] = $1}
>     FNR < NR {b[j++] = $1}
>     END {
>         for (i in a)
>             for (j in b)
>                 printf "%s%s\n", a[i], b[j] }
> ' file1 file2
AX
AY
AZ
BX
BY
BZ
CX
CY
CZ

答案 3 :(得分:0)

另一种使用 jq 的解决方案 有一个奖励......它从两个输入文件中过滤掉空行

jq -rn --rawfile f1 file1.txt --rawfile f2 file2.txt 
  'def seq: split("\n")[] | select(length > 0);
   {a: $f1|seq, b: $f2|seq} | .a + .b'