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

Replace whitespaces only after a match in sed or awk

我需要修改这组行

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 is the name of the file which I'm using to store the strings of text

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

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

编辑: 似乎其他解决方案只会处理 space 替换 space 之后的第一个 space =16=] 以下将处理所有 spaces.

awk 'match([=10=],/[^.]*/){val=substr([=10=],RSTART+RLENGTH);gsub(/ /,"_",val);print substr([=10=],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

如果您在一行中多次出现 .(spaces),请将上面的 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

用多个 spaces 测试了上面的代码: 假设我们在 spaces 之后有多个 spaces =16=] 然后 aboe 代码也可以工作。假设你的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

这里我更改了最后一行,在 . 之后添加了更多 spaces,现在在 运行 代码之后它将用单个 _ 替换它们,如下所示。

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(/ /,"_",)}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+)/_/;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+)/_/;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:]]*\)/_/;' -e 'ta' file

如果您确定您的行中没有尾随空格或者您希望尾随空格也被替换,您可以删除第二个 catch 组((...)\(...\))和 .

在任何 UNIX 机器上的任何 shell 中使用任何 awk:

$ awk 'p=index([=10=],"."){tl=substr([=10=],p+1); gsub(/ /,"_",tl); [=10=]=substr([=10=],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 将第 3 个参数匹配 () 和 gensub():

$ awk 'match([=11=],/([^.]+.)(.*)/,a){[=11=]=a[1] gensub(/ /,"_","g",a[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
20:22  25:04  05._here_is_a_dot._that_may_hurt._idk.

使用 sed(POSIX 兼容):

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

如果你只想用一个替换连续的空格_:

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

使用程序化文本编辑,您可以这样实现:

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

这可能适合您 (GNU sed):

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

_.

替换单词之前和之后的第三组空格

很多很棒的答案。我是 awk 的新手,但这是一个简单的解决方案

awk 'BEGIN{FS=OFS="  "} {gsub(/ /, "_", ); print [=10=]}' 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

这里是 awk 'BEGIN{FS=OFS=" "} {gsub(/ /, "_", ); print [=17=]}' InputFile

之后的 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

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

FS = 字段分隔符 = 两个 spaces(从 InputFile

中每两个 continue spaces 后识别出一个新字段

OFS = 输出字段分隔符 = 两个 spaces(在输出中每两个继续 spaces 后识别一个新字段..就像 Inputdata

gsub(/ /, "_", ) 将第 3 列中的一个 space " " 替换为下划线 _ ($3)

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

{print [=13=]}

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

$