sed中 N,D,P的使用

昨天工作中偶然拿到一个文本,几万行,需要把换行符替换为逗号“,” 遇到了遗漏已久的知识点,找到自己11年的一篇总结,回顾下。

先贴下解决问题的命令:

cat filename | sed ':a;N;s/\n/,/g;ta' // 换行符替换为","
sed '/./!d' filename //删除空行

以下是之前文章的回顾:

这里介绍的是sed的一个多行模式的使用,一开始对sed中命令N的用法不是很理解,经过多次尝试,通过几个例子对N的用法进行总结:

N即Next,它同n(next)的区别是:N命令将下一行追加到模式空间中,不打印模式空间的值,而使用n是打印当前模式空间的内容,并且读取下一行蒙受启发

> cat num
1
2
3
4
5
6
7
8
9
> sed ’N;$!D’ num
8
9
>

是如何执行的?

首先解释重要的几个命令的用途:

D删除模板块的第一行 并返回脚本头部执行

$ 锚定行的结束 如:/sed$/匹配所有以sed结尾的行 ,继续执行

! 表示后面的命令对所有没有被选定的行发生作用。
大概说一下:
N;$!D
首先读入第一行: 1 (注:这不是N命令读入的)
执行N,读入第2行,追加到1后面,成了1\n2;
$!D,不是最后一行,所以执行D,模式空间由1\n2成了2, 控制流返回脚本第一条命令,即N。这样一直执行
….
直到执行N读入第9行:9,这里模式空间为:8\n9
$!D,因为是最后一行,所以不执行D,控制流到达脚本底部,输出模式空间的内容:
8
9

上面这段例子摘自网络,给了我很大启发,另外测试如下:

关于N:

append the next line of input into the pattern space. 这是sed用户手册当中说的,很明显,意思是将当前读入行的下一行读取到当前的模式空间。

关于P:

Print up to the first embedded newline of the current pattern space.打印当前模式空间中的第一块。

关于D:

Delete up to the first embedded newline in the pattern space.  Start next cycle, but skip reading from  the  input if there is still data in the pattern space.

删除当前模式空间的第一块,重新开始下一次循环,这个在后面例子中给予验证:各种验证

验证一:NP结合

> cat num
1
2
3
4
> sed ’N;P’ num
1
1
2
3
3
4
> sed ’N;p’ num
1
2
1
2
3
4
3
4

对于上面的结果给予解释:P用于打印当前模式空间的第一块,而p打印整个当前模式空间。所以当使用P的时候,步骤如下:首先sed默认的读取1,模式空间为1,让你后执行N,模式空间变成1\n2\n,然后执行P,也就是打印1\n;当前行的处理,打印模式空间也就是1\n2\n;这时sed再从文件中读取下一行,也就到了3\n,执行N;模式空间变成了3\n4\n;

执行P;打印3\n;继续执行当前行的处理,打印模式空间3\n4\n;sed再从文件中读取下一行,发现没有了,结束处理流程。对于小p,和d大P的区别了解的话也就不难理解了。

验证二:ND结合

> cat num
1
2
3
4
> sed ’N;D’ num
4
> sed ’N;d’ num
>

对于D;删除当前模式空间第一块,并且返回命令开始继续执行。上述结果解释如下:

首先sed读取一行1\n;执行到N;模式空间为1\n2\n;执行D;模式空间变为:2\n;跳到前面继续执行N;模式空间变为2\n3\n;执行D;模式空间变为:3\n;跳回继续执行N;模式空间变为:3\n4\n;接着执行D;模式空间变为:4\n;跳回执行N的时候发现没有了下一行,所以跳出循环,接着sed继续处理,打印4\n;sed继续再读取文件的时候没有数据,所以结束处理。

验证3:NpD,再验证

> cat num
1
2
3
4
> sed ’N;p;D’ num
1
2
2
3
3
4
4

首先,sed读取一行,执行到N;模式空间为:1\n2\n;执行p;打印1\n2\n;执行D;模式空间变为:2\n;跳回执行N;模式空间变为:2\n3\n;执行p;打印2\n3\n;执行D;模式空间变为:3\n;跳回执行N;模式空间变为:3\n4\n;执行p;打印3\n4\n;执行D;模式空间变为:4\n;跳回执行N;没有数据。跳出循环,sed继续处理,默认打印模式空间所有数据4\n; 因此只有1打印一遍,其余行都打印2遍。

另外d和大D的区别了解以后也就明白了。

总结体会:sed处理始终在一个模式空间中进行,而且对于待处理文件,N读取了文件中的一行后,sed继续处理的时候应该是接着去读取,这里我理解是sed读取文件和N读取文件这些的共用一个指针。

在sed处理文件的时候,每一行都被保存在一个叫模式空间的临时缓冲区中,除非行被删除或者输出被取消,否则所有被处理的行都将 打印在屏幕上。接着模式空间被清空,并存入新的一行等待处理。

常用命令:

利用sed给每行添加行号。

> cat passwd
uucp:x:10:14:Unix-to-Unix CoPy system:/etc/uucp:/bin/bash
mqq:x:1000:100::/usr/local/app:/bin/bash
mysql:x:1001:1001::/home/mysql:/bin/bash
natpan:x:1002:100::/data/natpan:/bin/bash
nagios:x:1003:100::/home/nagios:/bin/bash
nagios:x:1003:100::/home/nagios:/bin/bash
nagios:x:1003:100::/home/nagios:/bin/bash

给每行加上行号,命令如下:

> sed = passwd | sed ’N;s/\n/:   /g’
1:   uucp:x:10:14:Unix-to-Unix CoPy system:/etc/uucp:/bin/bash
2:
3:   mqq:x:1000:100::/usr/local/app:/bin/bash
4:   mysql:x:1001:1001::/home/mysql:/bin/bash
5:   natpan:x:1002:100::/data/natpan:/bin/bash
6:   nagios:x:1003:100::/home/nagios:/bin/bash
7:   nagios:x:1003:100::/home/nagios:/bin/bash
8:   nagios:x:1003:100::/home/nagios:/bin/bash
mqq@wsd_207_62_sles10sp1:~/alenzhou/shell_test/sed>

空行不打印行号,做一下匹配就行

> sed ’/./=’ passwd | sed ’/./N;s/\n/:   /g’
1:   uucp:x:10:14:Unix-to-Unix CoPy system:/etc/uucp:/bin/bash
3:   mqq:x:1000:100::/usr/local/app:/bin/bash
4:   mysql:x:1001:1001::/home/mysql:/bin/bash
5:   natpan:x:1002:100::/data/natpan:/bin/bash
6:   nagios:x:1003:100::/home/nagios:/bin/bash
7:   nagios:x:1003:100::/home/nagios:/bin/bash
8:   nagios:x:1003:100::/home/nagios:/bin/bash

使用rsync做增量备份

原文写于 2011年8月18日 19:07
————————-
前言
我们经常需要数据的备份,包括日志信息,用户数据信息,用户上传数据信息之类,有些数据是不能单单依靠数据库来进行存储与备份。这是我们就会用到rsync,linux下的一个开源工具,非常强大的。我这块需要用到的是使用rsync做数据的增量备份,增量备份是什么概念,就是每次服务主机增加数据以后,同步到备机的时候只是传输增加部分的数据,因此备份的速度会很快,时间就是金钱么。另外,在主机上删除了某个文件,备份机却不会删除,这就是所谓的增量备份,也就不怕找不到误删的数据了,呵呵。然后就开搞吧,rsync的安装就不讲了,网上一搜一大堆。

 

第一步:

了解清楚需要备份的机器的信息:

需要备份的机器的IP(这里称作服务器吧):***.***.***.***

服务器需要备份的目录:/data/log

服务器需要验证的用户名和密码:username passwd

 

备份机IP(存放备份数据的地方):***.***.***.***

 

另外在需要备份的机器和备份机都需要安装rsync软件包

 

第二步:

服务器端相关的一些配置

vim /etc/rsyncd.conf

motd file = /etc/rsyncd.motd

pid file = /var/log/rsyncd.pid

log file = /var/log/rsyncd.log

lock file = /var/run/rsync.lock

 

uid = alenzhou

gid = alenzhou

 

use chroot = no

max connections = 100

##下面一定要有备份机的IP地址

hosts allow = 127.0.0.1,***.***.***.***

transfer logging = yes

timeout = 600

#refuse options = delete

##除过下列的文件。

dont compress = *.gz *.tgz *.zip *.z *.rpm *.deb *.iso *.bz2 *.tbz

##可以添加自己需要备份的模块

[log]

path = /data/log

comment = /data/log

ignore errors

read only = no

list = no

然后创建密码文件,格式为 用户:密码 都是明文

#vim /etc/rsyncd.secrets

username:passwd

 

在这些修改了的时候还有一个必须确认,就是rsync已经启动,如果没有,执行命令

rsync –daemon 就可以。

 

第三步:

客户机的配置以及备份脚本的编写

首先,需要有一个备份目录:$mkdir /data/logBackup

另外,在备份目录底下需要一个密码文件:

$ vim /data/logBackup/passwd

passwd  ##注意每行一个

 

下面是备份脚本:test.sh

#****************************************************

#  Author: alenchou.org@gmail.com

#  Last modified: 2011-08-17 21:39

#  Filename: test.sh

#  Description: backup files via rsyn

#****************************************************



#!/bin/bash



sendmail=/usr/local/support/bin/send_mail.pl



RSYNC_SERVER=**.**.**.**

AUTH_USER=user

BAKROOT=/data2/logBak10_135_2_165

[ ! -e $BAKROOT ] && mkdir -p $BAKROOT

PASSWD_FILE=$BAKROOT/passwd

PASSWD_PERM=`ls -l $PASSWD_FILE|awk '{print $1}'`

LOGFILE=$BAKROOT/backup.log

EXCLUDES=$BAKROOT/exclude_file



[ ! -e $EXCLUDES ] && touch $EXCLUDES



BACKUP_MODULES="logFlash logFlashMenagementdev logImg flashDoc"

OPTIONS="--force --ignore-errors --delete --delete-excluded --exclude-from=$EXCLUDES --password-file=$PASSWD_FILE --backup"



echo "-------------------"

echo  $?

rm -f $BAKROOT/log.*

log_id=0

for bakdir in $BACKUP_MODULES; do

    log_id=`expr $log_id + 1`;

echo "-------------------"

echo "$bakdir"

    rsync   -avzP $OPTIONS $AUTH_USER@$RSYNC_SERVER::$bakdir   $BAKROOT/$bakdir  | tee $BAKROOT/log.$log_id;

if [ $? != 0 ];then

          $sendmail "alenzhou"  "[10.147.22.112][`date +"%H:%M:%S"`] trans $bakdir failed.. "  "rsync error"

echo "[note.......................]  trans $bakdir failed."

else

echo "[note.......................]  trans $bakdir success."

fi

echo "end of $bakdir"

echo "-------------------"

done



##### end of test.sh   【修改于2011.8.19 18:57】

 

OK,这样,备份脚本就搞定,在每天的某个时间点执行命令./rsync.sh  就OK

可以使用crond来实现,这个就不介绍。

 

另外,可以在exclude_file 文件中加入不需要备份的子目录或者文件。支持通配符。

由于之前没使用过rsync,第一次使用做的总结,有不正确的地方欢迎指正啊。呵呵。

注意:这块使用–delete的时候会将服务器中没有的,而备份机中有的给删除掉,这里就是所谓的同步备份了,如果要使用增量备份的话需要在选项参数中加–update,同时去掉–delete,这样的话只要备份机的相同文件比服务器的旧,就会更新该文件,否则不动,这块可能会成为一个缺陷。

PDCA使用之道

周末参加了MTP管理培训,刘克葳老师的训练和场景化的介绍让我对管理这门艺术有了更深的理解,其中的一个重点就是我们常用的PDCA这个工具的注解。

1. Plan,事前计划部分

    目标明确,遵循SMART原则,这部分很重要,明确的目标对整个实施都是一个引导。
    掌握事实,了解自己所拥有的资源,不管是人力,技术等方面,这部分也非常关键,不能靠我以为来理解现状,做到事实的量化分析。
    方法标准,就是成员做事情要有同一个标准来衡量。
    流程步骤和节点规划,是执行过程中的连续性和节奏。
    应急预案,是要在计划阶段就确定的,以便在执行过程中能够快速应对突发状况。
    2. Do,执行部分
    择人任事,这个很关键,合适的人做合适的事情。
    状况共有,是这个环节最关键的,团队成员一定要信息对齐,避免成员间的信息不对齐导致理解偏差。
    下属执行,是指实际做事情不能是管理者亲力亲为,一定要充分授权到具体成员来执行。
    反馈特情,是要在执行过程中,对出现的异常情况及时反馈。
    3. Check,查核
    过程监督,过程中的关键环节要有效监督
    发现问题,在check环节,要充分发现问题,这点非常关键,不能掩盖问题或者忽视问题可能引发的风险。
    确认原因,在check阶段一定要对发现的问题明确原因
    4. Action,改善行动
    及时处理,执行力很重要,改善的措施要及时处理
    方法调整,对原规划当中的方式方法,如果确定有问题,要及时调整思路,调整方法。
    计划改善,要有计划的改善,逐渐回归到最终的预期
    状况共有,这个和Do阶段类似,要在改善行动过程中,确保干系人状况共有。

1分钟搞定wordpress更新时需要FTP服务器账户密码

更新时提示需要FTP服务器账户密码的话,一般是因为wordpress的目录权限不对,需要你提供有权限的用户名密码来解决,ftp的账户密码增加需要在你的服务器安装部署ftp,配置用户名密码这些,比较冗杂,这里提供一个便捷的方法。

首先进入到你的wordpress解压的路径,比如我的在/usr/share/wordpress;那就通过命令临时把目录权限修改为777,执行

chmod -R 777 /usr/share/wordpress

然后进入到wordpress的目录下,修改wp-config.php

vim wp-config.php

增加如下几行,保存退出

define("FS_METHOD", "direct");

define("FS_CHMOD_DIR", 0777);

define("FS_CHMOD_FILE", 0777);

然后刷新页面就可以了,切记更新完成后,修改目录为原来的权限,一般是755

chmod -R 755 /usr/share/wordpress

 

时隔10年,重新开始

记得大四那年,一方面追寻当时的博客热,想积累一些技术文章;一方面也为找工作积累一些资本,就维护了一段时间的博客,不过后来因为不可抗原因,没有坚持,心头这份写写文字的想法却是一直没有磨灭,不管是粗浅的技术方面,或者是随便瞎写。总之,这里可能还会在某个瞬间戛然而止,希望是许久之后。