Mik*_*ike 6 sed perl text-processing
我有一个文件,如:
ID_SOUR_CALENDAR BIGINT NOT NULL DEFAULT 0 COMPRESS 0 ,
UNIQUE PRIMARY INDEX ( CALENDAR_DATE );
ID ,
ID_SOUR ,
PRIMARY INDEX ( CALENDAR_DATE );
Run Code Online (Sandbox Code Playgroud)
我想在包含 PRIMARY 的行之前的行中用 ')' 替换 ','。
结果应该是:
ID_SOUR_CALENDAR BIGINT NOT NULL DEFAULT 0 COMPRESS 0 )
UNIQUE PRIMARY INDEX ( CALENDAR_DATE );
ID ,
ID_SOUR )
PRIMARY INDEX ( CALENDAR_DATE );
Run Code Online (Sandbox Code Playgroud)
使用GNU sed:
sed 'N;s/,\(\s*\n.*PRIMARY\)/)\1/;P;D' file
ID_SOUR_CALENDAR BIGINT NOT NULL DEFAULT 0 COMPRESS 0 )
UNIQUE PRIMARY INDEX ( CALENDAR_DATE );
ID ,
ID_SOUR )
PRIMARY INDEX ( CALENDAR_DATE );
Run Code Online (Sandbox Code Playgroud)
N 将下一行输入读取/追加到模式空间中。P 打印到当前模式空间的第一个嵌入换行符。D 最多删除模式空间中第一个嵌入的换行符。开始下一个循环,但如果模式空间中仍有数据,则跳过从输入中读取。尝试反转文件,在PRIMARY 之后的行上进行字符串替换,然后重新反转文件:
tac file | sed '/PRIMARY/ {n; s/,$/)/}' | tac
Run Code Online (Sandbox Code Playgroud)
尝试这个,
perl -0777 -pe 's/,([^\n,]*\n[^\n]*PRIMARY)/)$1/g'
Run Code Online (Sandbox Code Playgroud)
这将取代过去,用)的行之前的任何行,包括PRIMARY。
解释
perl -0777 吞下整个文件(读作一行)s/search_pattern/replacement/g 用全局替换替换搜索模式如果您使用ed而不是sed您可以使用具有负偏移量的正则表达式地址:
g/PRIMARY/-1 s/,$/)/
Run Code Online (Sandbox Code Playgroud)
前任。
$ printf 'g/PRIMARY/-1 s/,$/)/\n,p\nq\n' | ed -s file
ID_SOUR_CALENDAR BIGINT NOT NULL DEFAULT 0 COMPRESS 0 )
UNIQUE PRIMARY INDEX ( CALENDAR_DATE );
ID ,
ID_SOUR )
PRIMARY INDEX ( CALENDAR_DATE );
Run Code Online (Sandbox Code Playgroud)
或(用于就地编辑)
printf 'g/PRIMARY/-1 s/,$/)/\nwq\n' | ed -s file
Run Code Online (Sandbox Code Playgroud)
替换将匹配的所有实例/PRIMARY/- 如果您只想替换第一个,请删除g修饰符。