# sed-练习

# 常用的 sed 操作文件小指令

# 非注释行行末添加分号

sed.txt

i love cw LOVE
cw love me
we are family
we love each other love
to the world end

#1
# 222
# [123]
### 12312

   ## 11
   asdfsfdg
  • 其实可以写在一个正则里面,不过对于正则要求比较高,此方法采用了先添加分号,后删除以空格开头的非#注释内容的分号的方式完成需求,效果一样
sed -i '' -e 's/^[^#].*/&\;/g' -e 's/\([:blank:]*#.*\)\;$/\1/g' sed.txt

i love cw LOVE;
cw love me;
we are family;
we love each other love;
to the world end;

#1
# 222
# [123]
### 12312

   ## 11
   asdfsfdg;

# 查找文件内容练习

# 需求

输出 conf 文件中以[]划分的配置项的名称以及配置项个数,格式如下

1: client 2
2: server 12
3: mysqld 12
4: mysqld_safe 7
5: embedded 8
6: mysqld-5.5 10
# 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

#!/bin/bash
#

FILE_NAME=/Users/lijinchao/mySelf/code/Shell/case/sed/test/my.cnf

totalIndex=0

function get_all_segment() {
    title=$(sed -n '/^\[.*\]$/p' $FILE_NAME | sed -e 's/\[//' -e 's/\]//')
    echo $title
}

function count_items_in_segment() {
    index=$(sed -n "/^\[$1\]$/,/^\[.*\]$/p" $FILE_NAME | grep -v "^#" | grep -v "^$" | grep -v "\[.*\]" | grep -c ".*")
    # totalIndex=$(expr $totalIndex + 1) 不能写在这里无效
    echo $index
}

for sign in $(get_all_segment); do
    count=$(count_items_in_segment $sign)
    totalIndex=$(expr $totalIndex + 1)
    echo "$totalIndex: $sign $count"
done

# 要点总结

思路就是先截取到每一段的开头,以[]开始的这个比较好匹配,那么结尾形式不定不好确定,但是可以采用匹配下一个[]作为结尾就可以保证可以获取到所有内容(最后一个找不到下一个[]也会匹配至结尾),再用 grep 将其[]的行忽略掉即可。最后利用grep -c ".*" 统计出所有符合行的行数量即可

其中获取到[]内容之后要处理掉[],可以使用 sed -e 将其[和]替换成空的思路来去掉

  • echo 就是函数的返回值,一定记得写

  • grep -v "^$" 中^$匹配空行