如何使用bash将两个文本文件合并

4
我有两个文本文件,希望在bash中将其中一个文件的每一行与另一个文件的每一行组合起来。
file1.txt
abc123
def346
ghj098

file2.txt

PSYC1001
PSYC1002
PSYC1003

我想把它们结合起来,使得file1的第一行添加到file2的每一行之前,并用管道分隔符|隔开。
例如:
PSYC1001|abc123
PSYC1002|abc123
PSYC1003|abc123

然后对于文件1中的其他行也做同样的操作,这样最终我会得到:
PSYC1001|abc123
PSYC1002|abc123
PSYC1003|abc123
PSYC1001|def346
PSYC1002|def346
PSYC1003|def346
PSYC1001|ghj098
PSYC1002|ghj098
PSYC1003|ghj098<

我一直在用Bash复制这个网站上的示例做类似的简单文本操作,但我还没有找到一个可以做到这点的例子。很想听听你的建议。我知道这一定很简单,但我还没有解决它。
4个回答

5
最简单的一个 - join 命令:
join -j2 -t'|' -o2.1,1.1 file1 file2
  • -t'|' - 输入/输出字段分隔符
  • -o FORMAT - FORMAT 是一个或多个逗号或空格分隔的规范,每个规范都是 FILENUM.FIELD0

输出结果:

PSYC1001|abc123
PSYC1002|abc123
PSYC1003|abc123
PSYC1001|def346
PSYC1002|def346
PSYC1003|def346
PSYC1001|ghj098
PSYC1002|ghj098
PSYC1003|ghj098

4
这个awk单行命令可以帮助你:
awk -v OFS="|" 'NR==FNR{a[NR]=$0;c=NR;next}{for(i=1;i<=c;i++){print a[i],$0}}' file2 file1

使用您的数据进行测试:

kent$  awk -v OFS="|" 'NR==FNR{a[NR]=$0;c=NR;next}{for(i=1;i<=c;i++){print a[i],$0}}' f2 f1
PSYC1001|abc123
PSYC1002|abc123
PSYC1003|abc123
PSYC1001|def346
PSYC1002|def346
PSYC1003|def346
PSYC1001|ghj098
PSYC1002|ghj098
PSYC1003|ghj098 

3

以下是在纯bash中执行此操作的2种方式:

while IFS= read -u3 -r elem1; do 
    while IFS= read -u4 -r elem2; do 
        echo "$elem2|$elem1"
    done 4<file2.txt
done 3<file1.txt

mapfile -t f1 < file1.txt
mapfile -t f2 < file2.txt
for elem1 in "${f1[@]}"; do 
    for elem2 in "${f2[@]}"; do 
        echo "$elem2|$elem1"
    done
done

1

仅限bash

a1=( $(<f1) )
a2=( $(<f2) )

for i in "${a2[@]}"
do
 for j in "${a1[@]}"
  do
   echo "${j}|${i}"
 done
done

1
值得建议的伙计.. Glen的解决方案已经展示了如何做到这一点.. OP应该按照类似的方式去做。 - sjsam
这里的主要困难在于,如果输入文件包含空格或通配符与用户的文件匹配:a =($(cat file))for line in $(cat file)一样糟糕,因为它不存储/迭代而是单词 - glenn jackman

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接