【发布时间】:2014-09-22 16:01:30
【问题描述】:
inFile 中的第一列包含一个不一定存在于所有 inFiles 中的字符串
每个 inFile 中的第 2 和第 7 列包含 Title# 字符串
使用 AWK,我无法正确地将其拼凑在一起。我对描述性变量的使用有望帮助澄清我正在尝试做的事情。这些是我认为我需要的组件:
- 制表符分隔的输入文件:
-F'\t' - 增加第一列中的字符串,但每个“名称”只添加一次到“1stColumnNames”:
!1stColumnNames[$1]++ { name[++i] = $1 } - 为每个 .tsv 文件创建一个新索引来存储每个文件的值以避免覆盖每列的值:
!r[FILENAME]++ { ++argind } - 在每个文件的第 2 列和第 7 列中存储对应的列值:
{ 2ndColumnVals[$1, argind] = $2 } { 7thColumnVals[$1, argind] = $7 } - 打印所有 1stColumnNames 以及相关的 2ndColumnVals 和 7thColumnVals,包括它们的标题 'Title1' 'Title2' 'Title3' 等:
????? - 对于特定 2ndColumnVals 或 7thColumnVals 为空的索引值,打印为 Mtee:
????? - 对当前工作目录中的所有 .tsv 文件执行此操作并输出一个新的 tsv 文件:
*.tsv > outFile.tsv
示例文件
inFile1.tsv
Names Title1 Title2
AAAA 1111 123456
BBBBB 1111 123456
CCC 1111 123456
inFile2.tsv
Names Title3 Title4
BBBBB 2222 789456
DDDDD 2222 789456
EEEE 2222 789456
inFile3.tsv
Names Title5 Title6
AAAA 3333 987654
CCC 3333 987654
EEEE 3333 987654
outFile123.tsv
Names Title1 Title2 Title3 Title4 Title5 Title6
AAAA 1111 123456 Mtee Mtee 3333 987654
BBBBB 1111 123456 2222 789456 Mtee Mtee
CCC 1111 123456 Mtee Mtee 3333 987654
DDDDD Mtee Mtee 2222 789456 Mtee Mtee
EEEE Mtee Mtee 2222 789456 3333 987654
测试脚本
GNU Awk 4.0.1 位于 /usr/bin/awk ,所以我制作了这个文件并在 3 个输入文件所在的同一工作目录中执行它:
命名为 script1.sh#### Example Usage: script1.sh inFile1.tsv inFile2.tsv inFile3.tsv > outFile123.tsv
awk -F'\t' '
FNR==1 { ++numFiles}
!seen[$1]++ { keys[++numKeys] = $1 }
{ a[$1,numFiles] = $2 FS $3 }
END {
for (keyNr=1; keyNr<=numKeys; keyNr++) {
key = keys[keyNr]
printf "%s", key
for (fileNr=1;fileNr<=numFiles;fileNr++) {
printf "\t%s", ((key,fileNr) in a ? a[key,fileNr] : "Mtee\tMtee")
}
print ""
}
}
' "$@"
运行 awk -F script1.awk inFile1.tsv inFile2.tsv inFile3.tsv > outFile123.tsv 会打印以下错误消息:
awk: cmd. line:1: inFile1.tsv
awk: cmd. line:1: ^ syntax error
来自 konsolebox 的测试脚本 2
完美运行,但我试图通过评论来理解每一行:
#!/usr/bin/awk -f
#### named as script2.awk
#### Example Usage: awk -f script2.awk inFile1.tsv inFile2.tsv inFile3.tsv > outFile123.tsv
BEGIN { FS = "\t" } #input File Style is tab-delimited
{ sub(/\r/, "") } #remove all carriage return characters
!f[FILENAME]++ { ++indx } #for all files inputted make a single index called indx
!a[$1]++ { keys[i++] = $1 } #the new indx comprises only unique strings in column 1
{ b[$1, indx] = $2 FS $3 } #the 2nd and 3rd column are tab delimited and each pair that corresponds to a string saved in keys gets stored after the 1st column string in matrix b
END {
for (i = 0; i in keys; ++i) { #????
key = keys[i] #????
printf "%s", keys #prints out all strings in the index column 1 stored as keys
for (j = 1; j <= indx; ++j) { #????
v = b[key, j] #????
printf "\t%s", length(v) ? v : "Mtee" FS "Mtee" #print out strings as tab delimited and replace any lengths of 1 char to two Mtee separated by a tab
}
print "" #????
}
}
【问题讨论】:
-
+1 以获得清晰的描述、可测试的输入/输出,并努力自己解决!
-
script1.awk不是 awk 脚本,它是调用 awk 的 shell 脚本。为清楚起见,将其重命名为script1.sh,使其像任何其他shell 脚本一样可执行,将"$@"添加到awk 脚本的末尾,以便shell 将awk 传递给它的参数列表,然后以script1.sh inFile1.tsv inFile2.tsv inFile3.tsv > outFile123.tsv执行它。我编辑了你的问题以表明这一点。