仅在 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
$
我需要修改这组行
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
$