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

问题描述 投票:3回答:9

我需要修改这一系列的行

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

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

Expected Result:

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

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

regex awk sed text-processing
9个回答
3
投票

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

2
投票

这可能适合你(GNU sed):

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

在一个单词之前替换第三组空格,然后用_替换。


2
投票

编辑:似乎其他解决方案将只关注空间替换第一空间后qazxsw poi跟随将照顾所有空间。

.


如果您正在尝试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 之后有多个空格,那么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 之后添加了更多的空格,现在在运行代码后它将用单个.替换它们,如下所示。

_

1
投票

使用Perl

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

0
投票

在任何UNIX机器上的任何shell中都有任何awk:

$ 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

$

或者使用GNU awk为第3个arg匹配()和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

0
投票

使用sed(POSIX兼容):

$ awk 'match($0,/([^.]+.)(.*)/,a){$0=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.

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

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

0
投票

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

_

示例(添加一个边缘案例):

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

POSIX符合标准:

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 sed -e ':a' -e 's/\(\.[^[:space:]]*\)[[:space:]][[:space:]]*\([^[:space:]][^[:space:]]*\)/\1_\2/;' -e 'ta' file )和(...)


0
投票

使用Procedural Text Edit,您可以像这样实现:

\(...\)

0
投票

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

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

这是我的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

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

FS = Field Separator =两个空格(在InputFile每两个继续空格后识别一个新字段

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

awk 'BEGIN{FS=OFS=" "} {gsub(/ /, "_", $3); print $0}' InputFile用第3栏中的下划线替换一个空格“”($ 3)

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

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
© www.soinside.com 2019 - 2024. All rights reserved.