提前感谢您提出的任何想法。
我当前的项目让我尝试通过 geoiplookup 循环一个包含 1000 个 IP 地址列表的文件,并将其传送到 sed 以删除所有不符合条件的行。
该列表只是一个 IP 地址列表:
1.2.3.4
5.6.7.8
9.10.11.12
.
.
.
然后我geoiplookup ip.ad.dre.ss
以 root 身份运行,并得到:
[root@system ipset]# geoiplookup 4.2.2.2
GeoIP Country Edition: US, United States
如果 IP 在美国境内。
我的目标是,如果他们的 IP 不在美国,就从文件中删除所有行。
我尝试过的没有效果:
#!/bin/bash
for ip in $(cat /tmp/iplist.txt); do
geoiplookup $ip | sed '/GeoIP Country Edition: US, United States/!d'
done
有什么建议吗?如果能推荐其他方法,我们将不胜感激。
@terdon 抱歉我没有早点更新,我一直很忙。
向此问题或评论添加任何内容都会弄乱文本格式。抱歉,我是 Stack 的新手...让我来解决这个问题。
好的,更新。
更改并运行@terdon 的第一个代码后:
#!/bin/bash
while read ip; do
if ! geoiplookup "$ip" | grep -q ': US, United States$'; then
sed -i "/^$ip$/d" /tmp/iplist.txt
fi
done < /tmp/iplist.txt
它运行时没有错误,但非美国 IP 地址仍然在列表中。
我一直在使用最后一个例子declare -a badLines
scripts#geoiplookup 172.168.155.63
GeoIP Country Edition: GB, United Kingdom
scripts#grep 172.168.155.63 /tmp/iplist.txt
172.168.155.63
一旦我弄清楚如何让复制和粘贴直接作用于这里的问题,我就会更新。
@Ed Morton 这两个例子都在“done”行产生了同样的错误,一个是第 7 行,另一个是第 9 行。
./filter_ips.sh: line 7: syntax error near unexpected token `done'
./filter_ips.sh: line 7: ` done < "${@:--}"'
@Miri B 他们运行过了,但是列表中仍然有非美国的 IP 地址。
您需要循环遍历这些行,检查它们是否包含映射到美国的 IP,如果不包含,则从文件中删除该行。您的方法失败了,因为您使用的是命令
sed
的输出geoiplookup
,而不是文件。您需要做的是检查每个 IP,然后返回文件。因此,您可以执行如下操作(请注意,我
for i in $(cat file)
在这里没有使用;请参阅Bash 陷阱 #1了解为什么这是个坏主意):请注意,这还会删除无法映射到其位置的条目。例如,类似于此站点的内容:
如果你想保留它们,你可以使用这个:
但是,这两种方法都有点低效,因为它们需要多次处理整个文件。另一种方法是读取文件一次以生成要删除的行列表,然后用第二次传递删除它们。如下所示:
如果您传递
sed
命令,Nd
其中N
是一个数字,它将从其输入中删除该行号。因此,如果我运行sed 2d file
,则会打印出文件内容(第二行除外)。请记住,始终使用sed
,如果您希望更改实际保存在文件中,则需要-i
。因此sed -i 2d file
实际上会删除 的第二行file
。在这里,我读取文件一次并收集要删除的行号列表。然后,我将这个空格分隔的列表转换为
Nd;
使用小sed
命令的格式,最后,我将结果 sed 命令(看起来像2d;3d;130d;
等)传递sed
给实际修改文件。如果
geoiplookup
(我没有)一次只能处理 1 个 IP 地址,那么请考虑以下类似操作(未经测试):或者:
试试这两个 awk 代码:
或者另一个,可能更快: