Regex 仅在sed或awk中匹配后替换空白
我需要修改这组行Regex 仅在sed或awk中匹配后替换空白,regex,awk,sed,text-processing,Regex,Awk,Sed,Text Processing,我需要修改这组行 00:00 07:45 01. Alva 07:45 14:40 02. White Cliffs 14:40 20:22 03. Ribcage #1 20:22 25:04 04. I am Oidipus 匹配后(可能是点),我需要用破折号-或下划线-替换后面的空白 预期结果: 我已经尝试了以下方法,但结果参差不齐 dummyfile2是我用来存储文本字符串的文件名 给出结果: 00:00 07:45 01._Alva 07:45 14:40
00:00 07:45 01. Alva
07:45 14:40 02. White Cliffs
14:40 20:22 03. Ribcage #1
20:22 25:04 04. I am Oidipus
匹配后(可能是点),我需要用破折号-或下划线-替换后面的空白
预期结果:
我已经尝试了以下方法,但结果参差不齐
dummyfile2是我用来存储文本字符串的文件名
给出结果:
00:00 07:45 01._Alva
07:45 14:40 02._WhiteCliffs
14:40 20:22 03._Ribcage #1
20:22 25:04 04._I am Oidipus
00:00 07:45 01._Alva
07:45 14:40 02._Whit_Cliffs
14:40 20:22 03._Ribcag_#1
20:22 25:04 04.__a_Oidipus
我也试着做了以下几件事
sed -i 's/\(\.\)\(\s*\)/\1_/g' dummyfile2 | sed -i 's/\([[:alpha:]][[:space:]]\)\(\s*\)/_/g' dummyfile2
给出结果:
00:00 07:45 01._Alva
07:45 14:40 02._WhiteCliffs
14:40 20:22 03._Ribcage #1
20:22 25:04 04._I am Oidipus
00:00 07:45 01._Alva
07:45 14:40 02._Whit_Cliffs
14:40 20:22 03._Ribcag_#1
20:22 25:04 04.__a_Oidipus
最后一个是我能想到的最接近的。(但这不是预期的结果。)编辑:似乎其他解决方案将只处理空间替换
之后的第一个空间,后续将处理所有空间
awk 'match($0,/[^.]*/){val=substr($0,RSTART+RLENGTH);gsub(/ /,"_",val);print substr($0,RSTART,RLENGTH) val;next} 1' Input_file
00:00 07:45 01._Alva
07:45 14:40 02._White_Cliffs
14:40 20:22 03._Ribcage_#1
20:22 25:04 04._I_am_Oidipus
如果您正在尝试使用
sed
,以下内容可能会对您有所帮助。您不需要使用多个sed
命令
sed -E 's/\. +/\._/' Input_file
00:00 07:45 01._Alva
07:45 14:40 02._White Cliffs
14:40 20:22 03._Ribcage #1
20:22 25:04 04._I am Oidipus
更改sed-E的/\.+/\.\uu/'代码>到sed-E的/\。+/\_/g'
,以防在一行中多次出现
(空格)
如果您对awk
没有问题,请尝试以下内容
awk '{sub(/\. +/,"._")} 1' Input_file
如果多次出现
,则在上述命令中将sub
替换为gsub
。输出如下
00:00 07:45 01._Alva
07:45 14:40 02._White Cliffs
14:40 20:22 03._Ribcage #1
20:22 25:04 04._I am Oidipus
cat Input_file
00:00 07:45 01. Alva
07:45 14:40 02. White Cliffs
14:40 20:22 03. Ribcage #1
20:22 25:04 04. I am Oidipus
awk '{sub(/\. +/,"._")} 1' Input_file
00:00 07:45 01._Alva
07:45 14:40 02._White Cliffs
14:40 20:22 03._Ribcage #1
20:22 25:04 04._I am Oidipus
使用多个空格测试上述代码:假设之后有多个空格,那么aboe代码也可以工作。假设您的输入文件如下所示
00:00 07:45 01._Alva
07:45 14:40 02._White Cliffs
14:40 20:22 03._Ribcage #1
20:22 25:04 04._I am Oidipus
cat Input_file
00:00 07:45 01. Alva
07:45 14:40 02. White Cliffs
14:40 20:22 03. Ribcage #1
20:22 25:04 04. I am Oidipus
awk '{sub(/\. +/,"._")} 1' Input_file
00:00 07:45 01._Alva
07:45 14:40 02._White Cliffs
14:40 20:22 03._Ribcage #1
20:22 25:04 04._I am Oidipus
在这里,我更改了最后一行,在
之后添加了更多空格,现在在运行代码之后,它将用单个\uu
替换它们,如下所示
00:00 07:45 01._Alva
07:45 14:40 02._White Cliffs
14:40 20:22 03._Ribcage #1
20:22 25:04 04._I am Oidipus
cat Input_file
00:00 07:45 01. Alva
07:45 14:40 02. White Cliffs
14:40 20:22 03. Ribcage #1
20:22 25:04 04. I am Oidipus
awk '{sub(/\. +/,"._")} 1' Input_file
00:00 07:45 01._Alva
07:45 14:40 02._White Cliffs
14:40 20:22 03._Ribcage #1
20:22 25:04 04._I am Oidipus
awk
救援
$ awk 'BEGIN{FS=OFS="."} {gsub(/ /,"_",$2)}1' file
00:00 07:45 01._Alva
07:45 14:40 02._White_Cliffs
14:40 20:22 03._Ribcage_#1
20:22 25:04 04._I_am_Oidipus
使用GNU sed,您可以这样做:
sed -E ':a;s/(\.\S*)\s+(\S+)/\1_\2/;ta'
示例(添加了一个边缘案例):
POSIX sed兼容:
sed -e ':a' -e 's/\(\.[^[:space:]]*\)[[:space:]][[:space:]]*\([^[:space:]][^[:space:]]*\)/\1_\2/;' -e 'ta' file
sed -e :a -e 's/\(\.[^ ]*\) /\1_/;ta' file
如果您确定行中没有尾随空格,或者希望替换尾随空格,则可以删除第二个catch组((…)
或\(…)
)以及在任何UNIX框上的任何shell中带有任何awk的\2
:
$ awk 'p=index($0,"."){tl=substr($0,p+1); gsub(/ /,"_",tl); $0=substr($0,1,p) tl} 1' file
00:00 07:45 01._Alva
07:45 14:40 02._White_Cliffs
14:40 20:22 03._Ribcage_#1
20:22 25:04 04._I_am_Oidipus
或使用GNU awk匹配第三个参数()和gensub():
使用sed(符合POSIX标准):
如果您只想用一个\uu
替换连续空格:
sed -e :a -e 's/\(\.[^ ]*\) */\1_/;ta' file
通过程序文本编辑,您可以这样实现:
forEach line {
select (after ci ".") { findReplace ci " " "_" }
}
这可能适用于您(GNU-sed):
sed-E的/\s+\有很多很棒的答案。我不熟悉awk
,但这里有一个简单的解决方案
awk 'BEGIN{FS=OFS=" "} {gsub(/ /, "_", $3); print $0}' InputFile
这是我的InputFile
00:00 07:45 01. Alva
07:45 14:40 02. White Cliffs
14:40 20:22 03. Ribcage #1
20:22 25:04 04. I am Oidipus
00:00 07:45 01._Alva
07:45 14:40 02._White_Cliffs
14:40 20:22 03._Ribcage_#1
20:22 25:04 04._I_am_Oidipus
这是awk'BEGIN{FS=OFS=“”}{gsub(//,““,$3);print$0}输入文件之后的output
00:00 07:45 01. Alva
07:45 14:40 02. White Cliffs
14:40 20:22 03. Ribcage #1
20:22 25:04 04. I am Oidipus
00:00 07:45 01._Alva
07:45 14:40 02._White_Cliffs
14:40 20:22 03._Ribcage_#1
20:22 25:04 04._I_am_Oidipus
说明:
BEGIN=这段代码在读取文件之前执行,这意味着所有变量都可以在这里声明
FS=字段分隔符=两个空格(从InputFile中每隔两个连续空格识别一个新字段
OFS=输出字段分隔符=两个空格(在输出中每两个连续空格后识别一个新字段..与Inputdata一样
gsub(//,“quo,$3)
将第3栏中的一个空格“”替换为下划线($3)
最后,打印每一行,直到文件结束
{print $0}
使用Perl
$ perl -pe ' s/(?:\S+)\. (.+)$/$x=$&;$x=~s! !_!g;$x/ge ' whitespace.txt
00:00 07:45 01._Alva
07:45 14:40 02._White_Cliffs
14:40 20:22 03._Ribcage_#1
20:22 25:04 04._I_am_Oidipus
$
如果第一个
后面的文本也包含
s,并且对我来说它看起来像自由文本,那么我看不出任何理由认为它不能包含
s。您不需要第二次反向引用。与sed-E相同的输出:a;s/(\.\s*)/\1\uu/;ta'文件
@SLePort OP的样本数据中有尾随空格,显然OP不希望尾随空格被下划线替换。我们还可以通过代码(\s*\)来解释OP的意图
到。
OP希望用一个。
替换连续的多个空格。OP处理尾随空格的方式并不明显。这是示例数据,而不是源文件。尾随空格可能是复制和粘贴的结果。@SLePort C&P不会导致这种情况,可能是OP在发布后出现格式错误这是一个安全的方法。谢谢你给我的提示。我会在下一次发布一个问题后再考虑这个问题。