我正在编写一个脚本来跟踪路由表中的更改。该脚本每5分钟下拉一次路由表的快照,并将该表与5分钟的版本区分开来。如果文件中存在偏差,则脚本会生成电子邮件。问题是每一行还有一个年龄计数器,表示路线的年龄,因此该字段总是在变化。以下是来自生产路由器的修改后的快照:
修改 为了完整性,添加了具有秒和分钟年龄的路线。
B* 0.0.0.0/0 [200/0] via 1.0.10.121, 1d13h
[200/0] via 1.0.10.111, 1d13h
10.0.0.0/8 is variably subnetted, 159 subnets, 7 masks
O N1 10.0.0.1/32 [210/21] via 172.18.10.27, 1d13h, Vlan1503
O N1 10.1.0.0/16 [210/21] via 172.18.10.51, 2d17h, Vlan1506
O N1 10.2.0.0/16 [210/21] via 172.18.10.59, 2d17h, Vlan1507
B 10.10.0.0/16 [200/0] via 0.0.0.0, 2d17h, Null0
B 10.186.14.0/24 [200/0] via 1.0.10.124, 1d13h
[200/0] via 1.0.10.114, 1d13h
B 10.186.15.0/24 [200/0] via 1.0.10.124, 1d13h
O N2 10.192.32.0/21 [210/20] via 172.18.10.243, 2d17h, Vlan1508
O N2 10.192.40.0/21 [210/20] via 172.18.10.243, 2d17h, Vlan1508
B 10.193.0.0/24 [200/0] via 1.0.10.124, 1d13h
[200/0] via 1.0.10.114, 1d13h
C 172.18.10.232/29 is directly connected, Vlan1589
L 172.18.10.233/32 is directly connected, Vlan1589
B 205.1.2.3/27 [200/21] via 1.0.30.5, 2d17h
B 205.3.2.1/24 [200/20] via 1.0.30.5, 2d17h
O N1 2.2.2.2 [110/2] via 192.168.0.2, 00:08:48, Vlan1500
O N1 10.10.83.0/24 [210/21] via 172.18.10.27, 00:00:48, Vlan1503
注意所有" 2d17h," " 1d13h,"等等,这些是永远增加的年龄计数器,直到设备发生故障或链接振荡,然后它们重置。然而,路线的年龄对我来说并不重要,只是路线存在并且下一跳#34; (又名通过)没有改变。否则我只会" wc -l"这两个文件并确保长度相同。
从文件中剥离年龄计数器然后区分它们是否可行?如果是这样,删除计数器的最佳方法是什么?
谢谢!
编辑所需的输出相同,但删除了年龄计数器,如下所示:
B* 0.0.0.0/0 [200/0] via 1.0.10.121,
[200/0] via 1.0.10.111,
10.0.0.0/8 is variably subnetted, 159 subnets, 7 masks
O N1 10.0.0.1/32 [210/21] via 172.18.10.27, , Vlan1503
O N1 10.1.0.0/16 [210/21] via 172.18.10.51, , Vlan1506
O N1 10.2.0.0/16 [210/21] via 172.18.10.59, , Vlan1507
B 10.10.0.0/16 [200/0] via 0.0.0.0, , Null0
B 10.186.14.0/24 [200/0] via 1.0.10.124,
[200/0] via 1.0.10.114,
B 10.186.15.0/24 [200/0] via 1.0.10.124,
O N2 10.192.32.0/21 [210/20] via 172.18.10.243, , Vlan1508
O N2 10.192.40.0/21 [210/20] via 172.18.10.243, , Vlan1508
B 10.193.0.0/24 [200/0] via 1.0.10.124,
[200/0] via 1.0.10.114,
C 172.18.10.232/29 is directly connected, Vlan1589
L 172.18.10.233/32 is directly connected, Vlan1589
B 205.1.2.3/27 [200/21] via 1.0.30.5,
B 205.3.2.1/24 [200/20] via 1.0.30.5,
O N1 2.2.2.2 [110/2] via 192.168.0.2, , Vlan1500
O N1 10.10.83.0/24 [210/21] via 172.18.10.27, , Vlan1503
我想要防止的是两个相同的表(相同数量的路由,相同的下一跳)失败,因为其中一个路由年龄计数器在路由表的快照之间勾选。例如:
所以我的想法是,如果我剥离所有年龄计数器,差异不会失败。这可能不是实现监控路由表目标的最佳方法。不幸的是,我没有强大的脚本或编程背景。不过我对这些想法持开放态度,欢迎提出所有建议。 :)
答案 0 :(得分:0)
要从示例输入中删除年龄值,您可以匹配整个目标行的语法,而不是"大幅度更改时间戳"。
(很好地评论了你的评论摘要,谢谢。)
sed -E "s/(^[^.]*(([[:digit:]]+\.){3}[[:digit:]]+\/[[:digit:]]+| +).* via ([[:digit:]]+\.){3}[[:digit:]]+), [[:digit:]:dh]+/\1/"
(GNU sed版本4.2.1,即支持-E
)
-E
为方便起见,使用扩展正则表达式s/<start><blabla><IPa_or_spaces> via <IPb><, age><blabla><end>/<same_without_age>/
,我也删除了丑陋的&#34;,&#34;随着年龄增长。
如果您想保留替换),
- &gt; , )
,即在结肠空间之后而不是之前。
我认为这与sed有关的复杂性的高端,它接近sed-brain-teaser(这是我正在做的真正原因,为了好玩)。
此外,任何语法更改都可能会破坏这一点
所以仔细看看awk或perl中的答案,这些答案很快就会到来。 ;-)
然后使用你最舒服的任何东西,例如你自己最了解的语言/工具。
答案 1 :(得分:0)
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
tools:context="vmc.chesslys.MainActivity"
tools:showIn="@layout/app_bar_main">
<view
class="vmc.chesslys.CheckerBoard"
android:id="@+id/chessboard"
android:layout_width="fill_parent"
android:layout_height="fill_parent"/>
</android.support.constraint.ConstraintLayout>
以上内容适用于任何sed,除非是旧的POSIX之前的版本,如果这是你所拥有的,那么只需将public class MainActivity extends AppCompatActivity
implements NavigationView.OnNavigationItemSelectedListener {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
.setAction("Action", null).show();
}
});
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
drawer.setDrawerListener(toggle);
toggle.syncState();
NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
navigationView.setNavigationItemSelectedListener(this);
}
@Override
public void onBackPressed() {
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
if (drawer.isDrawerOpen(GravityCompat.START)) {
drawer.closeDrawer(GravityCompat.START);
} else {
super.onBackPressed();
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
@SuppressWarnings("StatementWithEmptyBody")
@Override
public boolean onNavigationItemSelected(MenuItem item) {
// Handle navigation view item clicks here.
int id = item.getItemId();
if (id == R.id.nav_camera) {
// Handle the camera action
} else if (id == R.id.nav_gallery) {
} else if (id == R.id.nav_slideshow) {
} else if (id == R.id.nav_manage) {
} else if (id == R.id.nav_share) {
} else if (id == R.id.nav_send) {
}
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
drawer.closeDrawer(GravityCompat.START);
return true;
}
}
更改为$ sed 's/\(via [0-9.]*, \)[[:alnum:]:]*/\1/' file
B* 0.0.0.0/0 [200/0] via 1.0.10.121,
[200/0] via 1.0.10.111,
10.0.0.0/8 is variably subnetted, 159 subnets, 7 masks
O N1 10.0.0.1/32 [210/21] via 172.18.10.27, , Vlan1503
O N1 10.1.0.0/16 [210/21] via 172.18.10.51, , Vlan1506
O N1 10.2.0.0/16 [210/21] via 172.18.10.59, , Vlan1507
B 10.10.0.0/16 [200/0] via 0.0.0.0, , Null0
B 10.186.14.0/24 [200/0] via 1.0.10.124,
[200/0] via 1.0.10.114,
B 10.186.15.0/24 [200/0] via 1.0.10.124,
O N2 10.192.32.0/21 [210/20] via 172.18.10.243, , Vlan1508
O N2 10.192.40.0/21 [210/20] via 172.18.10.243, , Vlan1508
B 10.193.0.0/24 [200/0] via 1.0.10.124,
[200/0] via 1.0.10.114,
C 172.18.10.232/29 is directly connected, Vlan1589
L 172.18.10.233/32 is directly connected, Vlan1589
B 205.1.2.3/27 [200/21] via 1.0.30.5,
B 205.3.2.1/24 [200/20] via 1.0.30.5,
O N1 2.2.2.2 [110/2] via 192.168.0.2, , Vlan1500
O N1 10.10.83.0/24 [210/21] via 172.18.10.27, , Vlan1503
。