1. 程式人生 > >正則表示式 linux shell 刪除偶數奇數行 取得最後一個字元 s/\(^.*$\)\n^.*$/\1/g

正則表示式 linux shell 刪除偶數奇數行 取得最後一個字元 s/\(^.*$\)\n^.*$/\1/g

alert(){
#Usage:alert <$?> <object>
if [ "$1" -ne 0 ]
then
    echo "WARNING:$2 did not complete succfully." >&2
    exit $1
else
    echo "INFO:$2 completed successfully." >&2
fi
}

成都<@qq.com> 10:29:42 
刪除偶數行:
%s/\(^.*$\)\n^.*$/\1/g
刪除奇數行:
%s/^.*$\n\(^.*$\)/\1/g

%s/\(^.*$\)\n^.*$/\1/g      vi 替換命令誰能幫忙講一下

雨後々清風 9:51:12 
全域性替換所有去掉特殊符號

北京@王帥 10:13:09 
\( \)   是所有內容
^  改行開頭
^. 開行開頭的第一個字元
* 後面跟的字元 
$ 換行
\n 換行
\1  這個不知道啥意思...

悠悠巷口10:15:53 
\1 是不 是代表第一個儲存的字串啊 
北京@王帥<[email protected]> 10:15:59 
不會.... 
北京@王帥<[email protected]> 10:16:06 
這個正則的功能是隔行刪除... 
北京@王帥<[email protected]> 10:16:10 
咋實現的  我不知道 

悠悠巷口 10:19:33 
\n^.*$/ 這個看不懂 
成都@itnihao<[email protected]> 10:21:10 
每行開頭
有點得字元
至結尾 
悠悠巷口(176481899) 10:21:41 
那它還用\n什麼作用 

 北京@王帥 10:22:04 
.不是代表有點的字元...
北京@王帥<[email protected]> 10:22:07 
點是萬用字元..
成都@itnihao 10:22:20 

悠悠巷口10:22:22 
也有這個作用
北京@王帥10:22:48  %s/\(^.*$\)\n^.*$/\1/g      vi 替換命令誰能幫忙講一下
%s/  語法
\(^.*$\)\n^.*$
/ 語法
\1

/g  語法

解釋: 正則表示式預備知識 注意到,對於正則表示式有 匹配 任意字元 ( 除換行符 ) .
匹配重複零次或多次前一字元 *
匹配集合中任意字元 [...]
匹配不屬集合 中 任意字元 [^...]
匹配 行首、行尾 ^, $
匹配 詞首、詞尾 \<, \>
正則表示式 分組 \(...\)
第 n 個分組內容 \n
於是 \1 表示第一個正則表示式分組即\(^.*$\) 我們暫將第一個正則表示式分組\(^.*$\)其記為:A 類推,\2就應該表示第二個正則表示式分組,即 \n^.*$  實際上 也應該寫在括號內比較好:\(\n^.*$\) ,我們也暫將第二個正則表示式分組 \n^.*$
記為:B
於是 %s/\(^.*$\)\n^.*$/\1/g
就可以寫為: %s/AB/A/g
即將所有AB都替換成A。

現在我們來分別分析A和B的作用。 A=\(^.*$\)
    抽取出來實際上是\(...\),表示正則表示式 分組,再分析括號內的^.*$,^代表行首,
.匹配 任意字元 ( 除換行符 ) , *匹配重複零次或多次前一字元 ,  $代表匹配到行尾,綜合起來就是:匹配這一行

B=\n^.*$
     解釋: \n換行,^.*$同上,表示匹配這一行,綜合起來就是:下一行(即上行結束後開始的另一行)。

再於是就有:%s/AB/A/g 即將所有AB都替換成B  ,代入A和B各自意思得到: 將兩行(如行1和行2 )內容替換為第一行內容(即行1的內容),加上/g,就是對全文進行前述替換,也就是隔行刪除,如果是從檔案第一行開始進行的操作,就意味著是刪除所有偶數行、保留所有奇數行操作。 刪除偶數行:
%s/\(^.*$\)\n^.*$/\1/g
刪除奇數行:
%s/^.*$\n\(^.*$\)/\1/g

補充另一例子: sed 's/\(.*\)\(.\)$/\2/' \2就應該表示第二個正則表示式分組 同上,也將A=/\(.*\),B=\(.\)$,表示式變為's/AB/B',將AB都替換成B 。 分析A、B作用。 A=/\(.*\)      抽取出來實際上是\(...\),表示正則表示式
分組,再分析括號內的 .*,表示匹配任意零個或多個字元 ( 除換行符 ) 
B=\(.\)$      括號內的 . ,表示匹配 任意字元 ( 除換行符
) ,括號外的$表示匹配到行尾,即表示行尾的最後一個字元;那上述的A /\(.*\)  就表示該行最後一個字元前的所有字元。
於是 sed 's/\(.*\)\(.\)$/\2/'
作用就是:刪除該行最後一個字元外的所有字元,保留最後一個字元,也即取得該行最後一個字元。
北京@王帥 10:23:37 
把語法的地方去掉  看具體內容
北京@王帥 10:25:18 
\(  ^. * $  \)  \n ^.*$
匹配整個文字\(\)
開頭位置字元匹配至結尾 匹配內容為第一個字元0個或者N個 制止改行結束   之後勳章換行符  再之後匹配開頭的第一個字元到結束 刪除一行. 

感謝王帥 和成都<itnihao 的提供的思路和答案。

案例

#!/usr/bin/env bash
APP="${project.artifactId}"
LOG_BASE="/home/admin/logs"
LOG_DIR="$LOG_BASE/$APP"
export PID_FILE="$LOG_DIR/$APP.pid"
export LANG="zh_CN.UTF-8"
export LC_ALL="zh_CN.UTF-8"
export JAVA_HOME=/home/admin/local/jdk1.7.0_79
export JAVA_BIN=$JAVA_HOME/bin
export JAVA_PATH=$JAVA_HOME/bin
export JAVA_OPTS="-Xms2048m -Xmx2048m -XX:MaxPermSize=256m"
export HADOOP_USER_NAME=hdfs
CONFIG_PATH=$(cd "$(dirname "$0")/../config";pwd)
LIB_PATH=$(cd "$(dirname "$0")/../lib";pwd)
# 組裝 CLASSPATH
ALL_JARS=$(ls "$LIB_PATH")
CLASS_PATH=""
for jar in $ALL_JARS
do
CLASS_PATH="$CLASS_PATH""$LIB_PATH""/""$jar"":"
done
CLASS_PATH=`echo $CLASS_PATH | sed -r 's/^(.*):$/\1/g'`