我有一个非结构化文件,我想搜索并替换字符串模式。
文件格式就像
col4 is required to be upper so
make col4 upper
abc 12345 !$% DATA SELECT
col1 as col1,
col2 as col2.
col3,
sch.col4 as col4,
sch.tab.col4 as col4_1,
col4,
col5 FROM sch.tab
xyz 34354 ^&* DATA SELECT
col5 as col5,
col3,
col4,
col4 as col4,
col4 FROM
blah blah blah
我要替换:
col4,
与upper(col4) as col4,
sch.col4
与upper(sch.col4)
sch.tab.col4
与upper(sch.tab.col4)
col4
(如果col4在选择查询的末尾)与upper(col4) as col4
该文件位于linux服务器上,我尝试使用sed和awk缩小包含col4的行,但无法从那里向前移动。
我可以使用以下内容识别一种模式
awk '/SELECT/,/FROM/' test_file.txt | awk '/col4/{print $0, NR}' | awk -F AS '{print $1}'
在SELECT和FROM之间找到文本
识别具有col4的行
打印第一个字段
sed -n -e '/SELECT/,/FROM/p' -e 's/\(\([a-zA-Z]\{1,\}\.\)\{0,\}\)col4/upper(\0)/g' test_file.txt
并使用sed
实际:
col4 is required to be upper so
make col4 upper
abc 12345 !$% DATA SELECT
col1 as col1,
col2 as col2.
col3,
sch.col4 as col4,
sch.tab.col4 as col4_1,
col4,
col5 FROM sch.tab
xyz 34354 ^&* DATA SELECT
col5 as col5,
col3,
col4,
col4 as col4,
col4 FROM
blah blah blah
预期结果:
col4 is required to be upper so
make col4 upper
abc 12345 !$% DATA SELECT
col1 as col1,
col2 as col2.
col3,
upper(sch.col4) as col4,
upper(sch.tab.col4) as col4_1,
upper(col4) as col4,
col5 FROM sch.tab
xyz 34354 ^& DATA SELECT
col5 as col5,
col3,
upper(col4) as col4,
upper(col4) as col4,
upper(col4) as col4 FROM
blah blah blah
非常感谢您的帮助!
答案 0 :(得分:0)
我认为至少有95%做到了。请告诉我是否有错误:
with open('ej.txt', 'r') as file:
string=file.read().replace('\n',' ')
import re
matches=re.findall(r'SELECT.*?FROM',string)
replacements={"col4,":"upper(col4) as col4,",
"sch.col4":"upper(sch.col4)",
"sch.tab.col4":"upper(sch.tab.col4)",
"col4 as col4,": "upper(col4) as col4,"}
new_matches=[]
for match in matches:
for k,v in replacements.items():
match=match.replace(k,v)
new_matches.append(match)
for k,v in {k:v for k,v in zip(matches,new_matches)}.items() :
string=string.replace(k,v)
string
答案 1 :(得分:0)
以下是执行您的请求的简短awk脚本:
awk '/SELECT/,/FROM/ {$0=gensub(/^[^[:space:]]*col4/,"upper(\\0)",-1);}1' input.txt
abc 12345 !$% DATA SELECT
col1 as col1,
col2 as col2.
col3,
upper(sch.col4) as col4,
upper(sch.tab.col4) as col4_1,
upper(col4),
col5 FROM sch.tab
xyz 34354 ^&* DATA SELECT
col5 as col5,
col3,
upper(col4),
upper(col4) as col4,
upper(col4) FROM
blah blah blah
/SELECT/,/FROM/
包含范围,从/ SELECT /到/ FROM /
$0=gensub(***)
使用gensub()中的替换来更新当前行
/^[^[:space:]]*col4/
在行首搜索col4的非空格前缀
upper(\\0)",-1
仅在第一次匹配时才将find-match替换为upper('found-match')
1
打印当前行。
1
答案 2 :(得分:0)
您对所需转换的描述不完整(例如,您说您想将col4,
更改为upper(col4) as col4,
,但是预期输出的第7行没有反映这一点),所以我将其放在一边刚刚写了这个,但是会从您提供的输入中产生您想要的输出(使用GNU awk将第三个arg匹配()),希望这是您真正想要的:
$ cat tst.awk
/SELECT/ { inBlock=1 }
inBlock {
if ( match($0,/^((sch\.(tab\.)?)?col4\>)( as .*)/,a) ) {
$0 = "upper(" a[1] ")" a[4]
}
else if ( match($0,/^(col4\>)(.*)/,a) ) {
$0 = "upper(" a[1] ") as " a[1] a[2]
}
}
/FROM/ { inBlock=0 }
{ print }
$ awk -f tst.awk file
col4 is required to be upper so
make col4 upper
abc 12345 !$% DATA SELECT
col1 as col1,
col2 as col2.
col3,
upper(sch.col4) as col4,
upper(sch.tab.col4) as col4_1,
upper(col4) as col4,
col5 FROM sch.tab
xyz 34354 ^&* DATA SELECT
col5 as col5,
col3,
upper(col4) as col4,
upper(col4) as col4,
upper(col4) as col4 FROM
blah blah blah
答案 3 :(得分:0)
使用sed:
sed '/SELECT/,/FROM/ {s/as col4 *//;s/\([A-Za-z]*\.\)\{0,\}col4/upper(&) as col4/;}' file
说明:
s/as col4 *//
:将现有的as col4
删除以防止第二次替换后出现重复\([A-Za-z]*\.\)\{0,\}col4
:搜索0个或更多字母和点的组合,后跟col4
upper(&) as col4/;
:替换为新文本(使用&
插入匹配的字符串)