仅在sed或awk中匹配后才替换空格

时间:2019-02-16 03:53:42

标签: 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

匹配(可能是点)之后,我需要用破折号-或下划线 _ 替换后面的空格(并且仅替换后面的空格)。

预期结果:

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是我用来存储文本字符串的文件的名称

sed -i 's/\(\.\)\(\s*\)/\1_/' dummyfile2 | sed -i 's/\(_\)\(\s*\)/\1_/' 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

我还尝试了以下操作...

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._Whit_Cliffs
14:40  20:22 03._Ribcag_#1 
20:22  25:04 04.__a_Oidipus

最后一个是我能想到的最近。 (但这不是预期的结果。)

9 个答案:

答案 0 :(得分:3)

$ 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 来营救!

{{1}}

答案 1 :(得分:2)

编辑: :似乎其他解决方案将只处理替换.之后的第一个空格的所有空格。

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 's/\. +/\._/'(空格)的情况下,将以上的sed -E 's/\. +/\._/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

上面的代码测试了多个空格: 假设我们在.之后有多个空格,那么上述代码也将起作用。假设您的Input_file如下。

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

答案 2 :(得分:2)

这可能对您有用(GNU sed):

sed -E 's/\s+\</_/3g' file

用单词_替换单词之前的第三组空白。

答案 3 :(得分:1)

使用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

$

答案 4 :(得分:0)

使用GNU sed,您可以这样做:

sed -E ':a;s/(\.\S*)\s+(\S+)/\1_\2/;ta'

示例(增加了一种边缘情况):

$ cat 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
20:22  25:04  05.U re  spe   cial

$ sed -E ':a;s/(\.\S*)\s+(\S+)/\1_\2/;ta' 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
20:22  25:04  05.U_re_spe_cial

符合POSIX sed:

sed -e ':a' -e 's/\(\.[^[:space:]]*\)[[:space:]][[:space:]]*\([^[:space:]][^[:space:]]*\)/\1_\2/;' -e 'ta' file

如果您确定行中没有尾部空格,或者您也希望替换尾部空格,则可以删除第二个捕获组((...)\(...\))和{{1} }。

答案 5 :(得分:0)

在任何UNIX盒子上的任何外壳中都有任何awk:

.setBackgroundColor(getResources().getColor(R.color.raj));

或使用GNU awk作为第三个参数,以match()和gensub():

$ 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

答案 6 :(得分:0)

使用sed(兼容POSIX):

sed -e :a -e 's/\(\.[^ ]*\) /\1_/;ta' file

如果您只想用一个_代替连续的空格:

sed -e :a -e 's/\(\.[^ ]*\)  */\1_/;ta' file

答案 7 :(得分:0)

使用过程文本编辑,您可以像这样实现它:

forEach line {
  select (after ci ".") { findReplace ci " " "_" }
}

答案 8 :(得分:0)

很多很好的答案。我是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

这是output之后的awk 'BEGIN{FS=OFS=" "} {gsub(/ /, "_", $3); print $0}' 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

说明:    BEGIN =该代码块在读取文件之前执行,这意味着所有变量都可以在此处声明

FS =字段分隔符=两个空格(在InputFile中每两个连续的空格之后便会识别一个新字段

OFS =输出字段分隔符=两个空格(就像在输入数据中一样,在输出..中每两个连续的空格之后就识别出一个新字段

gsub(/ /, "_", $3)在第3列($ 3)下划线_替换一个空格“”

最后,打印每一行直到文件结束

{print $0}