我的文件格式如下。请注意,这些条目是空格分开的。
16402 8 3858 3877 3098 3099
3858 -9.0743538e+01 1.5161710e+02 -5.4964638e+00
3244 -9.7903877e+01 1.8551400e-13 1.0194137e+01
3877 -9.2467590e+01 1.5160857e+02 -5.4969416e+00
4330 -9.3877419e+01 8.8259323e+01 -5.4966841e+00
3098 -9.2476135e+01 1.5336685e+02 -5.4963140e+00
5431 -6.1601208e+01 3.3540974e+01 1.0309820e+01
3099 -9.0752136e+01 1.5337535e+02 -5.4963264e+00
3600 -6.3099121e+01 1.3944173e+02 -5.4964156e+00
5418 -6.6785469e+01 2.9993099e+01 1.0291004e+01
有6个条目的行,有4个条目的文件。总共6个条目的行最后4个条目作为节点号,具有4个条目的行是具有空间坐标的那些节点号。我想只保留4个输入行中6个数字行中列出的节点,并删除所有其他节点,以便我的文件看起来像
16402 8 3858 3877 3098 3099
3858 -9.0743538e+01 1.5161710e+02 -5.4964638e+00
3877 -9.2467590e+01 1.5160857e+02 -5.4969416e+00
3098 -9.2476135e+01 1.5336685e+02 -5.4963140e+00
3099 -9.0752136e+01 1.5337535e+02 -5.4963264e+00
此文件已经创建了一些数据处理,因此保持格式很重要。我在文件中有数千行,6位数字条目和4位数字条目,因此一般解决方案对我学习和应用于其他案例也很有帮助。有关于sed或awk的任何建议吗?
感谢
答案 0 :(得分:0)
您可以使用以下awk脚本:
awk 'NF==6{print;b=b" "$3" "$4" "$5" "$6}NF==4{if(b ~ "\\y"$1"\\y") print}' input.txt
说明:
该命令管理一个缓冲区,该缓冲区包含六列的所有最后4个字段。该变量称为b
。每次awk
输入包含六列的行时,都会打印该行并将其附加到b
。
如果输入包含4列的行awk
,请使用函数b
检查$1
是否包含第一个字段match()
的值。
输出:
16402 8 3858 3877 3098 3099
3858 -9.0743538e+01 1.5161710e+02 -5.4964638e+00
3877 -9.2467590e+01 1.5160857e+02 -5.4969416e+00
3098 -9.2476135e+01 1.5336685e+02 -5.4963140e+00
3099 -9.0752136e+01 1.5337535e+02 -5.4963264e+00
注意,如果安全的是,具有6列的行仅适用于具有4列的以下行,直到出现具有6列的新行,则该命令可以更改为:
awk 'NF==6{print;b=b" "$3" "$4" "$5" "$6}NF==4{if(b ~ "\\y"$1"\\y") print}' input.txt
由于最大缓冲区大小只有一行,因此性能会好很多。
答案 1 :(得分:0)
我会将4个数字存储在一个数组中,然后测试数组中是否存在$ 1。
awk '
NF == 6 {
delete n
for (i=3; i<=NF; i++)
n[$i]=1
print
next
}
$1 in n
' file
答案 2 :(得分:0)
如果6场线始终出现在他们选择的4场线之前,那么
awk 'NF == 6 { for(i = 3; i <= 6; ++i) a[$i]; print } NF == 4 && $1 in a' filename
会奏效。具体如下:
NF == 6 { # in a six-field line:
for(i = 3; i <= 6; ++i) a[$i] # remember the relevant fields
print
}
NF == 4 && $1 in a # and subsequently select four-field lines
# by them
否则,您需要对文件进行第二次传递,并处理第二遍中第一个和第四个字段行中的六个字段行:
awk 'NR == FNR && NF == 6 { for(i = 3; i <= 6; ++i) a[$i]; print } FNR != NR && NF == 4 && $1 in a' filename filename