Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/bash/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Bash 在第二列中提取每一行,后跟一行具有不同值的行_Bash_Awk_Sed_Extract - Fatal编程技术网

Bash 在第二列中提取每一行,后跟一行具有不同值的行

Bash 在第二列中提取每一行,后跟一行具有不同值的行,bash,awk,sed,extract,Bash,Awk,Sed,Extract,给定以下文件结构 9.975 1.49000000 0.295 0 0.4880 0.4929 0.5113 0.5245 2.016726 1.0472 -30.7449 1 9.975 1.49000000 0.295 1 0.4870 0.5056 0.5188 0.5045 2.015859 1.0442 -30.7653 1 9.975 1.500

给定以下文件结构

9.975   1.49000000      0.295   0       0.4880  0.4929  0.5113  0.5245  2.016726        1.0472  -30.7449        1
9.975   1.49000000      0.295   1       0.4870  0.5056  0.5188  0.5045  2.015859        1.0442  -30.7653        1
9.975   1.50000000      0.295   0       0.5145  0.4984  0.4873  0.5019  2.002143        1.0854  -30.3044        2
是否有方法提取第二列中的值不等于下一行第二列中的值的每一行? 也就是说,我想从这三行中提取第二行,因为1.49不等于1.50。 也许是sed或awk

我在MATLAB中就是这样做的:

myline = 1;
mynewline = 1;
while myline < length(myfile)
    if myfile(myline,2) ~= myfile(myline+1,2)
        mynewfile(mynewline,:) = myfile(myline,:);
        mynewline = mynewline+1;
        myline = myline+1;
    else
        myline = myline+1;
    end
end
myline=1;
mynewline=1;
而myline<长度(myfile)
如果myfile(myline,2)~=myfile(myline+1,2)
mynewfile(mynewline,:)=myfile(myline,:);
mynewline=mynewline+1;
麦林=麦林+1;
其他的
麦林=麦林+1;
结束
结束
然而,现在我的文件太大了,我更愿意在将它们传输到我的笔记本电脑之前在终端中执行此提取。

Awk应该这样做

<data awk '($2 != prev) {print line} {line = $0; prev = $2}'
尝试以下命令:

awk '$2 != field && field { print line } { field = $2; line = $0 }' infile
它保存前一行和第二个字段,在下一个循环中与当前行值进行比较。
&&field
检查有助于避免在
$2!=字段
将匹配,因为变量为空

它产生:

9.975   1.49000000      0.295   1       0.4870  0.5056  0.5188  0.5045  2.015859        1.0442  -30.7653        1
这可能适用于您(GNU-sed):


一次读两行。模式匹配前两列,仅当第二列不匹配时才打印第一行。

不需要第一行-根据上面的示例,仅打印第二行。你能解释一下你的命令的作用吗?我现在正在尝试测试它,但什么也没发生。您没有指定数据的位置,所以我默认为stdin。要实际使用它,您需要将数据放在一个具有某个名称的文件中,比如说
data
,然后执行
Ah,明白了-但它会打印上面示例中的第三行。就我所理解的这一行而言,情况是这样的:我们最初将-1作为引用,然后遍历第2列并将每个值与引用进行比较。如果值不匹配,则打印当前行,并将参考值设置为此行第2列中的值。现在我只需要找出如何使它打印前一行!嗯,很抱歉误读了问题:)只需存储整行(
$0
)并有条件地输出即可。我会修好的。它几乎可以用了!有一件事我搞不懂:这个命令会产生三行中的两行,需要从给定的文件中提取出来。但是这个命令贯穿了文件的所有行,不是吗?。你能告诉我如何修改这个命令以打印(如果第二列不匹配)不仅第一行,而且最后n行吗?@Ango我不理解你的评论。示例比文字更好。注释中没有足够的空间用于示例:)我想知道如何修改此命令,使其能够执行以下操作:一次阅读两行。模式匹配前两列,当第二列不匹配时,仅打印第一行及其前一行。我想要做到这一点,一次需要读三行。
sed -r 'N;/^((\S+)\s+){2}.*\n\S+\s+\2/!P;D' file