删除空格 comm 输出
Remove blank spaces comm output
我有两个 ID 列表,我正在用 comm
命令进行比较。我的问题是输出看起来像这样:
YAL002W
YAL003W
YAL004W
YAL005C
YAL008W
YAL011W
我想做的就是尝试以某种方式对其进行管道传输,以便在写入文件时不带空空间,当我在 excel
中打开此文件时,它会转换为白色单元格。我已经尝试了我发现的所有可能的 grep、awk 和 sed 组合来删除空格而没有运气......
所以我得出的结论是列分别由一个或两个制表符分隔,因此我可以不要像删除空格而不删除文件格式那样容易地删除它们。
欢迎任何帮助或建议。
谢谢
编辑:
我希望我的输出为三列,制表符分隔且没有空格
YAL002W YAL004W YAL008W
YAL003W YAL005C
YAL011W
EDIT2 以避免引用的 XY 问题:
原问题(X):我必须列出并且我想在两个列表之间找到共同的和独特的词(稍后生成维恩图)。所以 comm
似乎是完美的解决方案,因为我同时获得了所有三个列表,稍后我可以轻松地将其导入 excel。
次要问题(Y):生成的三列不是三列(我开始这么想)因为我不能cut -f
它们,也不能删除空白通常使用 awk 'NF'
或 grep .
的空格(例如)。
给定此输入和 comm
输出:
$ cat file1
YAL002W
YAL003W
YAL008W
$ cat file2
YAL004W
YAL005C
YAL008W
YAL011W
$ comm file1 file2
YAL002W
YAL003W
YAL004W
YAL005C
YAL008W
YAL011W
这将满足您的要求:
$ cat tst.awk
BEGIN { FS=OFS="\t" }
{
colNr = NF
rowNr = ++rowNrs[colNr]
val[rowNr,colNr] = $NF
numCols = (colNr > numCols ? colNr : numCols)
numRows = (rowNr > numRows ? rowNr : numRows)
}
END {
for (rowNr=1; rowNr<=numRows; rowNr++) {
for (colNr=1; colNr<=numCols; colNr++) {
printf "%s%s", val[rowNr,colNr], (colNr<numCols ? OFS : ORS)
}
}
}
.
$ comm file1 file2 | awk -f tst.awk
YAL002W YAL004W YAL008W
YAL003W YAL005C
YAL011W
但是你当然可以跳过对 comm
的调用并立即使用 awk:
$ cat tst.awk
BEGIN { FS=OFS="\t" }
NR==FNR {
file1[[=13=]]
next
}
{
if ([=13=] in file1) {
colNr = 3
delete file1[[=13=]]
}
else {
colNr = 2
}
rowNr = ++rowNrs[colNr]
val[rowNr,colNr] = [=13=]
}
END {
for (v in file1) {
colNr = 1
rowNr = ++rowNrs[colNr]
val[rowNr,colNr] = v
}
numRows = (rowNrs[1] > rowNrs[2] ? rowNrs[1] : rowNrs[2])
numRows = (numRows > rowNrs[3] ? numRows : rowNrs[3])
numCols = 3
for (rowNr=1; rowNr<=numRows; rowNr++) {
for (colNr=1; colNr<=numCols; colNr++) {
printf "%s%s", val[rowNr,colNr], (colNr<numCols ? OFS : ORS)
}
}
}
.
$ awk -f tst.awk file1 file2
YAL002W YAL004W YAL008W
YAL003W YAL005C
YAL011W
使用 awk
并将 TAB 作为字段分隔符。找到第一个填写的字段,并将其添加到 multi-dimensional 数组的相应列中。为每一列使用单独的计数器,以便您填写该数组中的下一行。
awk -F'\t' 'BEGIN {col1=0; col2=0; col3=0; max=0; SUBSEP="\t"}
{ if (!out[max]) {out[max,1] = ""; out[max,2] = ""; out[max,3] = ""} }
length() { out[col1, 1] = ; if(col1 > max) max = col1++; next }
length() { out[col2, 2] = ; if(col2 > max) max = col2++; next }
length() { out[col3, 3] = ; if(col3 > max) max = col3++; }
END { for (i = 0; i < max; i++) { print(out[i]; }'
对于comm
的输出,列数是固定的,这里是量身定做的方案
$ awk 'BEGIN {FS=OFS="\t"}
{for(i=1;i<=3;i++)
if($i) {a[i,++c[i]]=$i; if(max<c[i]) max=c[i]}}
END {for(i=1;i<=max;i++) print a[1,i],a[2,i],a[3,i]}' file
YAL002W YAL004W YAL008W
YAL003W YAL005C
YAL011W
踢球,没有实施 comm
。
gawk '
NR == FNR {file1[[=10=]]; next}
[=10=] in file1 {common[[=10=]]; delete file1[[=10=]]; next}
{file2[[=10=]]}
END {
PROCINFO["sorted_in"] = "@ind_str_asc"
c=0; for (e in file1) v[1,++c] = e; max = c
c=0; for (e in file2) v[2,++c] = e; if (c > max) max = c
c=0; for (e in common) v[3,++c] = e; if (c > max) max = c
for (i=1; i<=max; i++)
printf "%s\t%s\t%s\n", v[1,i], v[2,i], v[3,i]
}
' file1 file2
YAL002W YAL004W YAL008W
YAL003W YAL005C
YAL011W
需要 GNU awk 才能使用 PROCINFO。
如需更多踢球,non-awk 回答
comm file1 file2 | ruby -e '
data = Array.new(3) {Array.new}
readlines.each {|line|
fields = line.chomp.split("\t")
data[fields.length - 1] << fields[-1]
}
m = data.map(&:length).max
data.collect {|lst| (lst + [""] * m).first(m)} # pad shorter lists
.transpose
.each {|row| puts row.join("\t")}
'
YAL002W YAL004W YAL008W
YAL003W YAL005C
YAL011W
我有两个 ID 列表,我正在用 comm
命令进行比较。我的问题是输出看起来像这样:
YAL002W
YAL003W
YAL004W
YAL005C
YAL008W
YAL011W
我想做的就是尝试以某种方式对其进行管道传输,以便在写入文件时不带空空间,当我在 excel
中打开此文件时,它会转换为白色单元格。我已经尝试了我发现的所有可能的 grep、awk 和 sed 组合来删除空格而没有运气......
所以我得出的结论是列分别由一个或两个制表符分隔,因此我可以不要像删除空格而不删除文件格式那样容易地删除它们。
欢迎任何帮助或建议。 谢谢
编辑:
我希望我的输出为三列,制表符分隔且没有空格
YAL002W YAL004W YAL008W
YAL003W YAL005C
YAL011W
EDIT2 以避免引用的 XY 问题:
原问题(X):我必须列出并且我想在两个列表之间找到共同的和独特的词(稍后生成维恩图)。所以 comm
似乎是完美的解决方案,因为我同时获得了所有三个列表,稍后我可以轻松地将其导入 excel。
次要问题(Y):生成的三列不是三列(我开始这么想)因为我不能cut -f
它们,也不能删除空白通常使用 awk 'NF'
或 grep .
的空格(例如)。
给定此输入和 comm
输出:
$ cat file1
YAL002W
YAL003W
YAL008W
$ cat file2
YAL004W
YAL005C
YAL008W
YAL011W
$ comm file1 file2
YAL002W
YAL003W
YAL004W
YAL005C
YAL008W
YAL011W
这将满足您的要求:
$ cat tst.awk
BEGIN { FS=OFS="\t" }
{
colNr = NF
rowNr = ++rowNrs[colNr]
val[rowNr,colNr] = $NF
numCols = (colNr > numCols ? colNr : numCols)
numRows = (rowNr > numRows ? rowNr : numRows)
}
END {
for (rowNr=1; rowNr<=numRows; rowNr++) {
for (colNr=1; colNr<=numCols; colNr++) {
printf "%s%s", val[rowNr,colNr], (colNr<numCols ? OFS : ORS)
}
}
}
.
$ comm file1 file2 | awk -f tst.awk
YAL002W YAL004W YAL008W
YAL003W YAL005C
YAL011W
但是你当然可以跳过对 comm
的调用并立即使用 awk:
$ cat tst.awk
BEGIN { FS=OFS="\t" }
NR==FNR {
file1[[=13=]]
next
}
{
if ([=13=] in file1) {
colNr = 3
delete file1[[=13=]]
}
else {
colNr = 2
}
rowNr = ++rowNrs[colNr]
val[rowNr,colNr] = [=13=]
}
END {
for (v in file1) {
colNr = 1
rowNr = ++rowNrs[colNr]
val[rowNr,colNr] = v
}
numRows = (rowNrs[1] > rowNrs[2] ? rowNrs[1] : rowNrs[2])
numRows = (numRows > rowNrs[3] ? numRows : rowNrs[3])
numCols = 3
for (rowNr=1; rowNr<=numRows; rowNr++) {
for (colNr=1; colNr<=numCols; colNr++) {
printf "%s%s", val[rowNr,colNr], (colNr<numCols ? OFS : ORS)
}
}
}
.
$ awk -f tst.awk file1 file2
YAL002W YAL004W YAL008W
YAL003W YAL005C
YAL011W
使用 awk
并将 TAB 作为字段分隔符。找到第一个填写的字段,并将其添加到 multi-dimensional 数组的相应列中。为每一列使用单独的计数器,以便您填写该数组中的下一行。
awk -F'\t' 'BEGIN {col1=0; col2=0; col3=0; max=0; SUBSEP="\t"}
{ if (!out[max]) {out[max,1] = ""; out[max,2] = ""; out[max,3] = ""} }
length() { out[col1, 1] = ; if(col1 > max) max = col1++; next }
length() { out[col2, 2] = ; if(col2 > max) max = col2++; next }
length() { out[col3, 3] = ; if(col3 > max) max = col3++; }
END { for (i = 0; i < max; i++) { print(out[i]; }'
对于comm
的输出,列数是固定的,这里是量身定做的方案
$ awk 'BEGIN {FS=OFS="\t"}
{for(i=1;i<=3;i++)
if($i) {a[i,++c[i]]=$i; if(max<c[i]) max=c[i]}}
END {for(i=1;i<=max;i++) print a[1,i],a[2,i],a[3,i]}' file
YAL002W YAL004W YAL008W
YAL003W YAL005C
YAL011W
踢球,没有实施 comm
。
gawk '
NR == FNR {file1[[=10=]]; next}
[=10=] in file1 {common[[=10=]]; delete file1[[=10=]]; next}
{file2[[=10=]]}
END {
PROCINFO["sorted_in"] = "@ind_str_asc"
c=0; for (e in file1) v[1,++c] = e; max = c
c=0; for (e in file2) v[2,++c] = e; if (c > max) max = c
c=0; for (e in common) v[3,++c] = e; if (c > max) max = c
for (i=1; i<=max; i++)
printf "%s\t%s\t%s\n", v[1,i], v[2,i], v[3,i]
}
' file1 file2
YAL002W YAL004W YAL008W
YAL003W YAL005C
YAL011W
需要 GNU awk 才能使用 PROCINFO。
如需更多踢球,non-awk 回答
comm file1 file2 | ruby -e '
data = Array.new(3) {Array.new}
readlines.each {|line|
fields = line.chomp.split("\t")
data[fields.length - 1] << fields[-1]
}
m = data.map(&:length).max
data.collect {|lst| (lst + [""] * m).first(m)} # pad shorter lists
.transpose
.each {|row| puts row.join("\t")}
'
YAL002W YAL004W YAL008W
YAL003W YAL005C
YAL011W