sed语法
基础介绍
sed(Stream Editor),流编辑器。对标准输出
或文件
逐行进行处理
语法
#第一种形式:对命令的结果进行处理
命令 | sed [option] '[pattern] command'
#第二种形式:对文件进行处理
sed [option] '[pattern] command' file
#[pattern] 是匹配模式,匹配到了才会执行command。如果不写pattern,就会对每一行都执行command
option (选项)
sed [
option
] '[pattern] command' 文件
-n 只在控制台打印匹配到的行
-e 直接在命令行进行sed编辑,是【默认选项】
-f 编辑动作保存在文件中,需要指定文件
-r 支持拓展正则表达内容
-i 直接修改文件内容
pattern (匹配模式)详解
sed [option] '[
pattern
] command' 文件
匹配模式 | 含义 |
---|---|
10command | 匹配第10行 |
10,20command | 匹配从第10行开始,到第20行结束 |
10,+5command | 匹配从第10行开始,到第10+5行结束 |
/pattern1/command | 所有匹配到pattern1的行 |
/pattern1/,/pattern2/command | 匹配到pattern1开始,到pattern2结束 |
10,/pattern1/command | 匹配从第10行开始,到匹配到pattern1结束 |
/pattern1/,10command | 匹配到pattern1行开始,到第10行结束 |
#1. 直接指定行号
sed -n "17p" file #打印file文件的第17行
#2.指定起始行号和结束行号
sed -n "10,20p" file #打印file文件的10~20行
#3.指定开始行号,以及之后N行
sed -n "10,+5p" file #打印file文件的第10行及之后的5行
#4.【常用!】所有正则表达式匹配到的行
sed - n "/^root/p" file #打印file文件中以root开头的行
#5.【常用!】从匹配到pattern1的行到pattern2的行
sed -n "/^ftp/,/^mail/p file" #打印file文件以ftp开头,到匹配pattern2截止
#6.从指定行号开始匹配,直到匹配到pattern1为止
sed -n "4,/^hdfs/p" file #打印file文件从第4行开始,到匹配到hdfs结束
#7.从匹配到pattern1开始,直到第n行
sed -n "/root/,10p" file =#打印file文件中从匹配到root的行开始,到第10行结束
匹配的时候,可以通过
sed [option] '/pattern1/command;/pattern2/command;/pattern3/command' 文件
的方式一次执行多条处理命令
command(编辑命令)详解
sed [option] '[pattern]
command
' 文件
类别 | 编辑命令 | 含义 |
---|---|---|
查询 | p | 打印 |
增加 | a | 行后追加 |
i | 行前追加 | |
r | 外部文件读入,行后追加 | |
w | 匹配行写入外部文件 | |
删除 | d | 删除 |
修改 | s/old/new | 将行内第一个old替换为new |
s/old/new/g | 将行内全部old替换为new | |
s/old/new/2g | 将行内的前2个替换为new | |
s/old/new/ig | 将行内全部old替换为new,且忽略大小写 |
sed使用案例
使用sed匹配
- 需求描述:
处理一个类似MySql配置文件my.cnf的文本,示例文件如下所示。
编写脚本实现:
输出文件有几段,并针对每个短可以统计配置参数的个数
预期实现效果:
1:client 2
2: servber 12
3: mysqld 12
4: mysqld_safe 7
5: embedded 8
6: mysqld-5.5 9
思路:
#确定需要定义哪些函数?
function get_all_segment #获取所有的段
function count_itemes_in_segment #每个段中包含配置项的个数
my.cnf
# this is read by the standalone daemon and embedded servers
[client]
port=3306
socket=/tmp/mysql.socket
#ThisSegmentForserver
[server]
innodb_buffer_pool_size=91750M
innodb_buffer_pool_instances=8
innodb_buffer_pool_load_at_startup=1
innodb_buffer_pool_dump_at_shutdown=1
innodb_data_file_path=ibdata1:1G:autoextend
innodb_flush_log_at_trx_commit=1
innodb_log_buffer_size=32M
innodb_log_file_size=2G
innodb_log_files_in_group=2
innodb_max_undo_log_size=4G
innodb_undo_directory=undolog
innodb_undo_tablespaces=95
#thisisonlyforthemysqldstandalonedaemon
[mysqld]
port=3306
socket=/tmp/mysql.sock
basedir=/usr/local/mysql
datadir=/data/mysql
pid-file=/data/mysql/mysql.pid
user=mysql
bind-address=0.0.0.0
sort_buffer_size=16M
join_buffer_size=16M
thread_cache_size=3000
interactive_timeout=600
wait_timeout=600
#ThisSegmentFormysqld_safe
[mysqld_safe]
log-error=/var/log/mariadb/mariadb.log
pid-file=/var/run/mariadb/mariadb.pid
max_connections=1000
open_files_limit=65535
thread_stack=512K
external-locking=FALSE
max_allowed_packet=32M
#thisisonlyforembeddedserver
[embedded]
gtid_mode=on
enforce_gtid_consistency=1
log_slave_updates
slave-rows-search-algorithms='INDEX_SCAN,HASH_SCAN'
binlog_format=row
binlog_checksum=1
relay_log_recovery=1
relay-log-purge=1
#usethisgroupforoptionsthatolderserversdon'tunderstand
[mysqld-5.5]
key_buffer_size=32M
read_buffer_size=8M
read_rnd_buffer_size=16M
bulk_insert_buffer_size=64M
myisam_sort_buffer_size=128M
myisam_max_sort_file_size=10G
myisam_repair_threads=1
lock_wait_timeout=3600
explicit_defaults_for_timestamp=1
innodb_file_per_table=1
脚本文件:mysql_process.sh
#!/bin/bash
#
#需要注意,正则表达匹配中括号时候,需要加入斜线转义
# 配置文件名和路径
FILE_NAME='./my.cnf'
# 获取所有的段的段名
function get_all_segments
{
#查找所有以[任意]开头的行,再把左右中括号替换为空,得到的就是段名
sed -n '/\[.*\]/p' $FILE_NAME | sed -e 's/\[//g' | sed -e 's/\]//g'
}
# 根据段名获取配置项个数
function count_items_in_segment
{
# 匹配以[参数1]开头,以[任意]结尾的行,排除注释行(#),排除空行($),最后排除所有[任意]的行,剩下的就是我们需要的配置行
items=$(sed -n '/\['$1'\]/,/\[.*\]/p' $FILE_NAME | grep -v "^#" | grep -v "^$" | grep -v "\[.*\]")
index=0
for item in $items
do
index=$(expr $index + 1)
done
echo $index
}
#先获取所有段,然后根据段名查看每个段内字段的个数
count=0
for each in $(get_all_segments)
do
count=$(($count + 1))
echo "$count: $each $(count_items_in_segment $each)"
done
使用sed删除
- 需求描述
- 删除配置文件中所有注释行和空行
- 在配置文件中所有不以#开头的行前面添加*号
nginx.conf
# For more information on configuration, see:
# * Official English Documentation: http://nginx.org/en/docs/
# * Official Russian Documentation: http://nginx.org/ru/docs/
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;
# Load dynamic modules. See /usr/share/nginx/README.dynamic.
include /usr/share/nginx/modules/*.conf;
events {
worker_connections 1024;
}
http {
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
include /etc/nginx/mime.types;
default_type application/octet-stream;
upstream www_servers {
server 192.168.1.70:80 weight=1;
server 192.168.1.80:80 weight=1;
}
# Load modular configuration files from the /etc/nginx/conf.d directory.
# See http://nginx.org/en/docs/ngx_core_module.html#include
# for more information.
include /etc/nginx/conf.d/*.conf;
server {
listen 192.168.1.129:80 default_server;
server_name _;
root /usr/share/nginx/html;
# Load configuration files for the default server block.
include /etc/nginx/default.d/*.conf;
location / {
proxy_pass http://www_servers;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $remote_addr;
}
error_page 404 /404.html;
location = /40x.html {
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
}
}
# Settings for a TLS enabled server.
#
# server {
# listen 443 ssl http2 default_server;
# listen [::]:443 ssl http2 default_server;
# server_name _;
# root /usr/share/nginx/html;
#
# ssl_certificate "/etc/pki/nginx/server.crt";
# ssl_certificate_key "/etc/pki/nginx/private/server.key";
# ssl_session_cache shared:SSL:1m;
# ssl_session_timeout 10m;
# ssl_ciphers HIGH:!aNULL:!MD5;
# ssl_prefer_server_ciphers on;
#
# # Load configuration files for the default server block.
# include /etc/nginx/default.d/*.conf;
#
# location / {
# }
#
# error_page 404 /404.html;
# location = /40x.html {
# }
#
# error_page 500 502 503 504 /50x.html;
# location = /50x.html {
# }
# }
}
执行语句
#删除配置文件中所有注释行和空行
sed -i '/^#/d;/^$/d;/[:blank:]*#/d' ./nginx.conf
#在配置文件中所有不以#开头的行前面添加*号
sed -i 's/^[^#]/\*&/g' nginx.conf
#(&代表反向引用,此处&其实就指匹配到的整行信息,然后我们在前面加*号。如果不使用&,会将非#号开头的行的第一个字符替换成*)
Comments NOTHING