bash使用空替换连接多个文件(-e选项)

Ami*_*mir 6 linux bash join

我有以下代码将多个文件连接在一起.它工作正常,但我想将空值替换为0,所以我使用-e"0".但它不起作用.有任何想法吗?

for k in `ls file?`
do
    if [ -a final.results ]
    then
            join -a1 -a2 -e "0" final.results $k  > tmp.res
            mv tmp.res final.results
    else
            cp $k final.results
    fi

done
Run Code Online (Sandbox Code Playgroud)

例:

file1: 
a 1 
b 2
file2:
a 1 
c 2
file3:
b 1 
d 2

Results:
a 1 0 1 0
b 2 1 0
c 2
d 2

expected:
a 1 1 0
b 2 0 1
c 0 2 0
d 0 0 2
Run Code Online (Sandbox Code Playgroud)

cmh*_*cmh 6

它的文档记录不充分,但是在使用join-e选项时只能与该-o选项结合使用。每次在循环中都需要修改订单字符串。以下代码应生成所需的输出。

i=3
orderl='0,1.2'
orderr=',2.2'
for k in $(ls file?)
do
    if [ -a final.results ]
    then
            join -a1 -a2 -e "0" -o "$orderl$orderr" final.results $k  > tmp.res
            orderl="$orderl,1.$i"
            i=$((i+1))
            mv tmp.res final.results
    else
            cp $k final.results
    fi
done
Run Code Online (Sandbox Code Playgroud)

如您所见,它开始变得混乱。如果您需要进一步扩展它,可能值得使用功能更强大的工具,例如awk或python。

  • 不要解析`ls`的输出!在文件中使用`for k ?; 代替。 (2认同)

Wil*_*ken 6

另外,GNU版本的join支持-o auto.在-e-o引起足够的挫折把人们学习AWK.(另请参阅如何使用Unix join获取外连接中的所有字段?).正如cmh所说:它没有记录,但是当使用join时,该-e选项只能与-o选项一起使用.

一般解决方案

cut -d ' ' -f1 file? | sort -u > tmp.index
for k in file?; do join -a1 -e '0' -o '2.2' tmp.index $k > tmp.file.$k; done
paste -d " " tmp.index tmp.file.* > final.results
rm tmp*
Run Code Online (Sandbox Code Playgroud)

额外奖励:我如何比较git中的多个分支?

for k in pmt atc rush; do git ls-tree -r $k | cut -c13- > ~/tmp-branch-$k; done
cut -f2 ~/tmp-branch-* | sort -u > ~/tmp-allfiles
for k in pmt atc rush; do join -a1 -e '0' -t$'\t' -11 -22 -o '2.2' ~/tmp-allfiles ~/tmp-branch-$k > ~/tmp-sha-$k; done
paste -d " " ~/tmp-allfiles ~/tmp-sha-* > final.results
egrep -v '(.{40}).\1.\1' final.results # these files are not the same everywhere
Run Code Online (Sandbox Code Playgroud)