加入多个文件的循环,填充空字段

时间:2017-11-16 17:21:15

标签: bash loops unix join

我想在第1列加入28个文件,保留每个迭代连接的两个文件的所有结果,并用0填充空列。总共有两列。前3个文件的预期输入和输出:

File1中

// Set the rounded edge for the outer bar
self.layer.cornerRadius = 12
self.clipsToBounds = true

// Set the rounded edge for the inner bar        
self.layer.sublayers![1].cornerRadius = 12
self.subviews[1].clipsToBounds = true

文件2

a   1       
b   2       
c   1       
d   4       

文件3

a   2       
b   3   

加入

c   2       
d   2       
e   1       

我已经在我的实际文件上使用管道写出了整个连接,它可以工作,但显然很麻烦。为清楚起见,我在这里用省略号缩短了它:

a   1   2   0
b   2   3   0
c   1   0   2
d   4   0   2
e   0   0   1

我知道这可以循环添加新字段,但我是编程和循环的新手不是我的强项。我试过这个(从这里bash join multiple files with empty replacement (-e option)):

join -t $'\t' -a 1 -a 2 -e '0' -o 0 1.2 2.2 -1 1 -2 1 *D3-E-N-1*/*matrix.txt.cut *D3-E-N-2*/*matrix.txt.cut | join -t $'\t' -a 1 -a 2 -e '0' -o 0 1.2 1.3 2.2 -1 1 -2 1 - *D3-E-N-3*/*matrix.txt.cut | join -t $'\t' -a 1 -a 2 -e '0' -o 0 1.2 1.3 1.4 2.2 -1 1 -2 1 - *D3-E-N-4*/*matrix.txt.cut | join -t $'\t' -a 1 -a 2 -e '0' -o 0 1.2 1.3 1.4 1.5 2.2 -1 1 -2 1 - *D3-E-N-5*/*matrix.txt.cut | ... > final.matrix.txt

给了我错误

  

[:参数太多

     

[:参数太多

     

cp:覆盖'final.results'?

有没有人对脚本提出递归加入文件的建议,或者有更适合此任务的程序?

非常感谢!

2 个答案:

答案 0 :(得分:1)

只需使用R,您就可以根据需要更改所需的扩展名:

以下是我用作示例的文件:

<强> f1.txt

a 1
b 4
c 6
e 3

<强> f2.txt

c 1
d 4
f 5
z 3

<强> f3.txt

a 1
b 4
c 5
e 7
g 12

R代码:

#!/bin/env/Rscript

ext='.ext' #can alter this to desired extension
files <- list.files(pattern=ext) #get name of files in a directory
listOfFiles <- lapply(files, function(x){ read.table(x, row.names=1) } )

#The big reduction of all the files into a table
tbl <- Reduce(function(...) data.frame(merge(..., all = T, by = 0), row.names=1), listOfFiles)

tbl[is.na(tbl)] <- 0 #set all NA vals to 0
colnames(tbl) <- files #set the columns to the corresponding filenames (optional)
tbl #print out the table

<强>输出:

  f1.ext f2.ext f3.ext
a      1      0      1
b      4      0      4
c      6      1      5
d      0      4      0
e      3      0      7
f      0      5      0
g      0      0     12
z      0      3      0

答案 1 :(得分:0)

我很惊讶你的管道工作;我自己无法工作。此外,您的输入文件和输出文件似乎不匹配。但除此之外:

Join只会加入两列:一个键和一个字段。这意味着您需要一些方法将键与字段分开,否则您将松开以前连接的列。

例如: F1:

a   1
b   2
c   1
d   4

F2:

a   2
b   3

F3:

c 2    d 2    e 1

$ join -a1 -a2 -e "0" -t'       ' -o "0,1.2,2.2" f1 f2
a   1   2
b   2   3
c   1   0
d   4   0
$ join -a1 -a2 -e "0" -t'       ' -o "0,1.2,2.2" f1 f2 > f4
$ join -a1 -a2 -e "0" -t'       ' -o "0,1.2,2.2" f4 f3
a   1   0
b   2   0
c   1   2
d   4   2
e   0   1

这不是你想要的。

您可以将第一个标签更改为;并加入然后更改回来,但是如果后面的文件引入了新的密钥,那么它将为你提供第一个文件中不存在的密钥的半行。

仅使用键将文件添加到连接中将创建一个必须删除的列的列。

您可能有一些外卡可以列出您的所有文件,在我的示例中可能是f?,但您的可能是file.**.cols等。请尝试使用外卡与ls确定无关。

所以,把它放在一起:

#first make a key-file k0
cat f?  | cut -f1  | sort -u > k0
# change the separator to ';' and back
for f in f? ; do
    sed 's/\t/;/' k0 > t0
    sed 's/\t/;/' $f > t1
    join -a1 -a2 -e "0" -t';' -o "0,1.2,2.2" t0 t1 | sed 's/;/\t/g' > k0
done
# remove the '0' column from the key-file
sed 's/\t0\t/\t/' k0

或看看awk。