JOIN 无法识别存储在 MAPFILE 元素中的文件名



我正在尝试通过共享查找列(第一列(连接 65 个文件。我正在命令行上测试部分代码,并且使用作为 JOIN 输入的 MAPFILE 元素存在问题。我尝试了几种不同的方法来回显MAPFILE的元素,但没有成功。当我用它们所代表的文件名替换元素时,它可以正常工作。如何将 MAPFILE 的元素传递给 JOIN?

cat list.txt | ( mapfile -t; echo "${MAPFILE[@]}" ) | join -11 -21 -a1 -a2 -o1.1,1.2,2.2 -e0 ${MAPFILE[1]} ${MAPFILE[2]} >countmatrix.txt

尝试的其他策略:

cat list.txt | ( mapfile -t; echo "${MAPFILE[@]}" ) | (file1=$(echo ${MAPFILE[1]}); file2=$(echo ${MAPFILE[2]})) | join -1 -2 -a -o1.1,1.2,2.2 -e0 $file1 $file2 >countmatrix.txt
cat list.txt | ( mapfile -t; echo "${MAPFILE[@]}" ) | (file1=$(echo ${MAPFILE[1]}); file2=$(echo ${MAPFILE[2]}); join -11 -21 -a1 -a2 -o1.1,1.2,2.2 -e0 <(sort $file1) <(sort $file2) >countmatrix.txt)

两次引用的尝试都不起作用,因为它们尝试在一个子外壳中读取 MAPFILE,并使用管道的第二个子外壳中的值。在 sh* shell 中,变量从父子 shell 传递到子子 shell。管道的每个元素都在作为主外壳的子壳体的子壳中执行。

因此,管道一部分的变量不适用于管道的其他部分。(例如A=5 | echo $A将不起作用(。

在这种情况下:

  1. "(mapfile ...("在子shell中执行,读取MAPFILE
  2. "join"是在单独的不相关的子shell中执行的,不能使用MAPFILE

简单的解决方案是读取主外壳(或中间子外壳(中的映射文件,如下所示

# Read MAPFLE
mapfile -t < list.txt
# EXecute join, use  MAPFILE
join -11 -21 -a1 -a2 -o1.1,1.2,2.2 -e0 ${MAPFILE[1]} ${MAPFILE[2]} >countmatrix.txt

从表面上看,不需要将任何内容通过管道传输到 join 命令中,该命令使用命名文件进行输入(忽略 stdin(。

"真正的"解决方案(65 个文件(应该在循环中包含联接,而不是单个联接。

您正在子外壳和分配的变量中执行mapfile${MAPFILE[@]}无法从父进程访问。

请尝试以下操作:

cat list.txt | ( mapfile -t; echo "${MAPFILE[@]:0:2}" ) | xargs join -11 -21 -a1 -a2 -o1.1,1.2,2.2 -e0 > countmatrix.txt

考虑到list.txt中定义的文件名包含空格的情况 和/或其他特殊字符,可以更安全地说:

cat list.txt | ( mapfile -t; printf "%s" "${MAPFILE[@]:0:2}" ) | xargs -0 join -11 -21 -a1 -a2 -o1.1,1.2,2.2 -e0 > countmatrix.txt

相关内容

最新更新