我有一个文本文件,其中包含许多行,格式如下
001_A.wav;112.680;115.211;;;Ja. Hello; Hi:
我的目标是清理;;;
之后的任何东西。意味着删除以下字符,;()~?
我知道我可以做一些类似sed 's/[,.;()~?,]//g'
的事情。然而,如果我这样做,它会给我一些类似的东西
001_Awav112.680115211Ja Hello Hi
然而,我想只在;;;
之后删除这些字符,这样我就会得到
001_A.wav;112.680;115.211;;;Ja Hello Hi
我该如何完成这项任务?
第一个解决方案:
请您尝试以下内容,用GNUawk
中显示的示例编写和测试(其中假设;;;
在行中出现一次(。
awk '
match($0,/.*;;;/){
laterPart=substr($0,RSTART+RLENGTH)
gsub(/[,.:;()~?]/,"",laterPart)
print substr($0,RSTART,RLENGTH) laterPart
}' Input_file
解释:添加以上详细解释。
awk ' ##Starting awk program from here.
match($0,/.*;;;/){ ##Using atch function to match everything till ;;; here.
laterPart=substr($0,RSTART+RLENGTH) ##Creating variable laterPart which has rest of the line apart from matched regex part above.
gsub(/[,.:;()~?]/,"",laterPart) ##Globally substituting ,.:;()~? with NULL in laterPart variable.
print substr($0,RSTART,RLENGTH) laterPart ##Printing sub string of matched regex and laterPart var here.
}' Input_file ##Mentioning Input_file name here.
第二个解决方案:如果行中多次出现;;;
,并且您希望替换所有字段中的字符,则在第一次出现;;;
之后,请尝试以下操作。
awk 'BEGIN{FS=OFS=";;;"} {for(i=2;i<=NF;i++){gsub(/[,.:;()~?,]/,"",$i)}} 1' Input_file
您可以使用
sed ':a; s/(;;;[^,.:;()~?,]*)[,.:;()~?,]/1/; ta' file > newfile
sed ':a; s/(;;;[^[:punct:]]*)[[:punct:]]/1/; ta' file > newfile
详细信息
:a
设置标签(;;;[^,.:;()~?,]*)[,.:;()~?,]
匹配并捕获到组1中的;;;
子字符串,然后是除,.:;()~?,
字符之外的任何零个或多个字符,然后仅匹配,.:;()~?,
集合中的一个字符[^[:punct:]]*
匹配除标点符号字符以外的任何0个或多个字符[[:punct:]]
匹配任何标点符号字符1
为替换,第1组内容ta
在成功替换时分支回a
标签
请参阅在线sed
演示:
s='001_A.wav;112.680;115.211;;;Ja. Hello; Hi:'
sed ':a; s/(;;;[^,.:;()~?,]*)[,.:;()~?,]/1/; ta' <<< "$s"
# => 001_A.wav;112.680;115.211;;;Ja Hello Hi
sed ':a; s/(;;;[^[:punct:]]*)[[:punct:]]/1/; ta' <<< "$s"
# => 001_A.wav;112.680;115.211;;;Ja Hello Hi
没有正确阅读您的问题,但我现在已经更改了。
我建议使用perl
,因为它有查找组。
$ perl -pe 's/^((?:(?!;;;).)*;;;)|[:,.;()~?,]/1/g' file.txt
^
是该行的开头((?:(?!;;;).)*;;;)
是[^;]*
的字符串等价物,并确保找到第一个;;;
,并将其分组在1
中- CCD_ 26选择字符CCD_。(因此在其中留下"Ja"(
您可以将一些sed
命令与组合使用
echo '001_A.wav;112.680;115.211;;;Ja. Hello; Hi:' |
sed 's/;;;/;;;nr/' |
sed '/^r/ s/[,;():~?]//g' |
sed -z 's/;;;nr/;;;/g'
不同的GNUAWK
解决方案:
echo "001_A.wav;112.680;115.211;;;Ja. Hello; Hi:" | awk 'BEGIN{FS=OFS=";;;"}{print $1,gensub(/[,;()~?]/,"","g",substr($0,length($1)+1))}'
输出:
001_A.wav;112.680;115.211;;;Ja. Hello Hi:
这假设您的描述优先于示例(仅删除,;()~?
(。说明:我使用;;;
作为分隔符,然后输出分隔符Iprint
第1列(;;;
之前的内容(,并通过查找其开头为第1列的长度加1来获得其余部分,然后从该部分删除所有指定字符并打印它。如果示例优先于描述,那么您可以使用[[:punct:]]
字符集,即:
echo "001_A.wav;112.680;115.211;;;Ja. Hello; Hi:" | awk 'BEGIN{FS=OFS=";;;"}{print $1,gensub(/[[:punct:]]/,"","g",substr($0,length($1)+1))}'
将给出
001_A.wav;112.680;115.211;;;Ja Hello Hi