一个过滤条件,两个文件

时间:2017-08-02 12:48:38

标签: file unix awk data-cleaning

我有一个看起来像这样的文件

VAR1    VAR2    VAR3    VAR4
ID1     foo     0.1     0.1
ID2     foo     1       1
ID3     foo     foo     .
ID4     foo     foo     foo
ID5     foo     .       1
ID6     foo     -0.1    -0.1
ID7     foo     -1      -1
ID8     foo     5e-08   5e-08

我想根据一系列连续的条件筛选出行(例如,首先删除第3列中的所有非数字条目,然后从第4列删除所有非数字条目),但我想保存满足这些中间条件的所有行。也就是说,我的最终输出应该是1)包含在第一步中删除的所有行的文件,2)包含在下一步中删除的所有行的文件,以及3)包含在过滤中幸存的所有行的文件。

到目前为止我得到的是:

awk '$3!=$3*1  {print}' < file.txt > REMOVED_COL_3.txt
if [[ $( find REMOVED_COL_3.txt -type f -size +0c 2>/dev/null ) ]]
then
awk '$3==$3*1' < file.txt > tmp.txt && mv tmp.txt file.txt
fi
awk '$4<0 {print}' < file.txt > REMOVED_COL_4.txt
if [[ $( find REMOVED_COL_4.txt -type f -size +0c 2>/dev/null ) ]]
then
awk '$4>=0 {print}' < file.txt > tmp.txt && mv tmp.txt file.txt
fi

哪个有效,但在我的真实数据集中需要花费大量时间(预过滤约1300万行)。

是否可以awk一次并将其保存在一个文件中的符合条件的行和那些不在另一个文件中的行?或其他什么?

编辑: 我忘记了文件中的标题

2 个答案:

答案 0 :(得分:2)

这在单个awk脚本中非常有用。您可以在import matplotlib.pyplot as plt import numpy as np from matplotlib.ticker import AutoMinorLocator def sin_func(array): final = np.array([]) for value in array: final = np.append(final, abs(np.sin(value))) return final x = np.arange(0, 4*np.pi, 0.1) y = sin_func(x) fig = plt.figure() ax = fig.add_subplot(111, projection='polar') plt.plot(x, y) # Changing axis to pi scale ax.set_ylim([0, 1.2]) x_tick = np.arange(0, 2, 0.25) x_label = [r"$" + format(r, '.2g') + r"\pi$" for r in x_tick] ax.set_xticks(x_tick*np.pi) ax.set_xticklabels(x_label, fontsize=10) ax.set_rlabel_position(110) # Add Cartesian axes ax2 = fig.add_axes((.1,.1,.0,.8)) ax2.xaxis.set_visible(False) # hide x axis ax2.set_yticks(np.linspace(0,1,7)) # set new tick positions ax2.set_yticklabels(['60 %','40 %', '20 %', '0 %', '20 %', '40 %', '60 %']) ax2.yaxis.set_minor_locator(AutoMinorLocator(2)) # set minor tick for every second tick plt.show() 中使用if/else if/else,也可以将各个awk语句重定向到不同的文件:

print

答案 1 :(得分:1)

awk '
NR==1 {
    split("REMOVED_COL_3.txt REMOVED_COL_4.txt tmp.txt",outfiles)
    for (outnr in outfiles) {
        print > outfiles[outnr]
    }
    next
}
{
    if ($3 != $3+0)  { outnr=1 }
    else if ($4 < 0) { outnr=2 }
    else             { outnr=3 }
    print > outfiles[outnr]
}
' file.txt &&
mv tmp.txt file.txt

我使用$3+0代替$3*1将字符串转换为数字,因为添加通常比乘法快一点,这是执行该操作的更常见方式,请参阅{ {3}}:To force a string to be converted to a number, add zero to that string.