我有一个数字列表文件。
号码列表
0000000 00eb 00f4
0000003
,还有另一个文件,该文件是要删除的数字列表,仅一次
numers_to_remove
40426
140
26
3502
140
899320
所以输出文件应该是
140
3502
仅删除一次,以使140保持不变,因为它在list_of_numbers中出现了两次。
我现在正在做
40426
26
140
899320
有什么更快的方法来进行bash吗? 我将在此之后对这些数字进行排序,因此数字的顺序并不重要。
答案 0 :(得分:0)
一个sed
应该快很多:
list_of_numbers=(
40426 140 26
3502 140 899320
)
numbers_to_remove=(
140 3502
)
printf "%s\n" "${list_of_numbers[@]}" |
sed "$(printf '0,/^%d$/s///\n' "${numbers_to_remove[@]}")/^$/d"
将输出:
40426
26
140
899320
printf
重复它的格式字符串作为参数。因此printf "A %d" 1 2
将输出A 1A 2
。sed
参数格式设置为0,/^<number here>$/s///<newline>
。换行符用于分隔sed
命令。sed
命令用于删除空行,即。 /^$/d
-删除没有内容的行。答案 1 :(得分:0)
首先将要删除的所有数字存储在数组中。
处理完第一个文件(FNR==NR
)后,继续第二个文件。
在remove数组中找到值后,将其从数组中删除并查看下一行。
当值不在数组中时打印它。
awk 'FNR==NR{a[$0];next}
$0 in a{delete a[$0];next}
{print}' numbers_to_remove list_of_numbers
答案 2 :(得分:0)
with awk-这确实需要预排序的记录。只要两个文件使用相同的排序方案,顺序就无关紧要。
awk '
BEGIN{ getline skipnum < "numbers_to_remove"; old=""; }
{ if ( $0 == skipnum && old != skipnum ) {
old = skipnum;
getline skipnum < "a";
next;
} else print;
}
' list_of_numbers
BEGIN
从列表中预读一行以跳过。
在每个记录上,如果设置了skipnum并与当前行匹配,
-然后尝试读取下一个skipnum-失败应将其保留为空。
-next
跳过打印该记录。
否则打印当前记录。
这是对每个文件的快速单次读取。
如果您不想对其进行预排序,则使用关联数组并删除找到的每个元素。
awk '
BEGIN {
while (getline skipnum < "numbers_to_remove") { skips[skipnum] = 1; }
}
{ if ( $0 in skips ) {
delete skips[$0];
next;
} else print;
}
' list_of_numbers