我试图将多个文件与主文件密钥合并。 我的主文件是这样的
cat files.txt
哪个有钥匙,想比较......
1
2
3
4
5
6
7
8
9
10
11
其他输入文件
cat f1.txt
1 : 20
3 : 40
5 : 40
7 : 203
cat f2.txt
3 : 45
4 : 56
9 : 23
想要这样的输出..
f1 f2 ....
1 20 NA
2 NA NA
3 40 45
4 56 NA
5 40 NA
6 NA NA
7 203 NA
8 NA NA
9 23 NA
10 NA NA
11 NA NA
尝试了这个,但无法打印不匹配的密钥
awk -F':' 'NF>1{a[$1] = a[$1]$2}END{for(i in a){print i""a[i]}}' files.txt *.txt
1 20
3 40 45
4 56
5 40
7 203
9 23
请有人指导我这里缺少什么吗?
答案 0 :(得分:1)
复杂的GNU awk 解决方案(考虑到系统资源,将涵盖任意数量的文件):
awk 'BEGIN{
PROCINFO["sorted_in"]="@ind_num_asc"; h=" ";
for(i=2;i<=ARGC;i++) h=(i==2)? h ARGV[i]: h OFS ARGV[i]; print h
}
NR==FNR{ a[$1]; next }{ b[ARGIND][$1]=$3 }
END{
for(i in a) {
printf("%d",i);
for(j in b) printf("%s%s",OFS,(i in b[j])? b[j][i] : "NA"); print ""
}
}' files.txt *.txt
示例性输出:
f1 f2
1 20 NA
2 NA NA
3 40 45
4 NA 56
5 40 NA
6 NA NA
7 203 NA
8 NA NA
9 NA 23
10 NA NA
11 NA NA
PROCINFO["sorted_in"]="@ind_num_asc"
- 排序模式(数字按升序排列)
for(i=2;i<=ARGC;i++) h=(i==1)? h ARGV[i]: h OFS ARGV[i]
- 迭代脚本参数,收集文件名。
ARGC
和ARGV
使命令行参数可用于您的程序
答案 1 :(得分:0)
$ cat awk-file
NR==FNR{
l=NR
next
}
NR==FNR+l{
split(FILENAME,f1,".")
a[$1]=$3
next
}
NR==FNR+l+length(a){
split(FILENAME,f2,".")
bwk -v OFS='\t' -f awk-file files.txt f1.txt f2.txt[$1]=$3
next
}
END{
print "",f1[1],f2[1]
for(i=1;i<=l;i++){
print i,(a[i]!="")?a[i]:"NR",(b[i]!="")?b[i]:"NR"
}
}
$ awk -v OFS='\t' -f awk-file files.txt f1.txt f2.txt
f1 f2
1 20 NR
2 NR NR
3 40 45
4 NR 56
5 40 NR
6 NR NR
7 203 NR
8 NR NR
9 NR 23
10 NR NR
11 NR NR
我为你的问题修改了答案。 如果您有第3个,第4个文件(假设为第n个文件),请添加n个新块,如下所示
NR==FNR+l+length(a)+...+length(n){
split(FILENAME,fn,".")
n[$1]=$3
}
在End
区块中,
END{
print "",f1[1],f2[1],...,fn[1]
for(i=1;i<=l;i++){
print i,(a[i]!="")?a[i]:"NR",(b[i]!="")?b[i]:"NR",...,(n[i]!="")?n[i]:"NR"
}
}
答案 2 :(得分:0)
使用awk和sort -n
对输出进行排序:
$ awk -F" *: *" '
NR==FNR {
a[$1]; next }
FNR==1 {
for(i in a)
a[i]=a[i] " NA"
h=h OFS FILENAME
}
{
match(a[$1]," NA")
a[$1]=substr(a[$1],1,RSTART-1) OFS $2 substr(a[$1],RSTART+RLENGTH)
}
END {
print h
for(i in a)
print i a[i]
}' files f1 f2 |sort -n
f1 f2
1 20 NA
2 NA NA
3 40 45
4 56 NA
5 40 NA
6 NA NA
7 203 NA
8 NA NA
9 23 NA
10 NA NA
11 NA NA
陷阱:1。sort
在某些情况下会因标题而失败。 2.由于NA
已替换为值$2
,因此您的数据不能包含NA
个起始字符串。替换/ NA( |$)/
可能会避免这种情况,但可能会导致更多的代码检查,因此请仔细选择NA
。 :d
修改强>:
运行它,例如,四个文件:
$ awk '...' files f1 f2 f1 f2 | sort -n
1 20 20 NA NA
2 NA NA NA NA
3 40 45 40 45
4 56 56 NA NA
5 40 40 NA NA
6 NA NA NA NA
7 203 203 NA NA
8 NA NA NA NA
9 23 23 NA NA
10 NA NA NA NA
11 NA NA NA NA
答案 3 :(得分:0)
$ cat tst.awk
ARGIND < (ARGC-1) { map[ARGIND,$1] = $NF; next }
FNR==1 {
printf "%-2s", ""
for (fileNr=1; fileNr<ARGIND; fileNr++) {
fileName = ARGV[fileNr]
sub(/\.txt$/,"",fileName)
printf "%s%s", OFS, fileName
}
print ""
}
{
printf "%-2s", $1
for (fileNr=1; fileNr<ARGIND; fileNr++) {
printf "%s%s", OFS, ((fileNr,$1) in map ? map[fileNr,$1] : "NA")
}
print ""
}
$ awk -f tst.awk f1.txt f2.txt files.txt
f1 f2
1 20 NA
2 NA NA
3 40 45
4 NA 56
5 40 NA
6 NA NA
7 203 NA
8 NA NA
9 NA 23
10 NA NA
11 NA NA
以上使用GNU awk进行ARGIND,其他awks只在脚本开头添加一行FNR==1{ARGIND++}
。
答案 4 :(得分:-1)
请使用以下脚本进行处理。 FILESPATH包含输入文件列表(f1.txt,f2.txt ...)。 INPUT有输入文件(files.txt)。
var http = require('http'),
url = require('url'),
fs = require('fs');
var express = require('express')
, app = module.exports = express();
var router=express.Router();
//var fs = require('fs');
// string generated by canvas.toDataURL()
router.get('/', function(req, res, next){
var img =
"Right_9660009901_20170707_172902_1023927555.jpg";
// strip off the data: url prefix to get just the base64-encoded bytes
var fs = require("fs");
fs.writeFile("image.jpg", new Buffer(img, "base64"), function(err) {});
});
====== 您可以使用printf而不是echo来更好地格式化输出。
答案 5 :(得分:-1)
这可以通过简单的循环和echo语句来完成。
#!/bin/bash
NA=" NA"
i=0
#print header module start
header[i]=" "
for file in `ls f[0-9].txt`;
do
first_part=`echo $file|cut -d. -f1`
i=$i+1
header[i]=$first_part
done
echo ${header[@]}
#print header module end
#print elements start
for element in `cat files.txt`;
do
var=$element
for file in `ls f[0-9].txt`;
do
var1=`grep -w ${element} $file`
if [[ ! -z $var1 ]] ; then
field2=`echo $var1|cut -d":" -f2`
var="$var$field2"
else
var="$var$NA"
fi
done
echo $var
done
#print elements end