Bash 替换多个块中特定图案之间的任何字符

Bash 替换多个块中特定图案之间的任何字符,bash,awk,sed,Bash,Awk,Sed,我有一个类似的问题,但我不能适应我的情况 假设我有一个包含许多行的文件: f 1/1/519 2/2/2 3/3/520 f 287/4/521 1/5/519 3/6/520 f 5/7/522 1/8/523 287/9/524 我想替换每个块的两个斜杠number/anyNumber/number之间的内容 我希望得到以下结果: f 1//519 2//2 3//520 f 287//521 1//519 3//520 f 5//522 1//523 287//524 正确

我有一个类似的问题,但我不能适应我的情况

假设我有一个包含许多行的文件:

f  1/1/519 2/2/2 3/3/520
f  287/4/521 1/5/519 3/6/520
f  5/7/522 1/8/523 287/9/524
我想替换每个块的两个斜杠number/anyNumber/number之间的内容

我希望得到以下结果:

f  1//519 2//2 3//520
f  287//521 1//519 3//520
f  5//522 1//523 287//524
正确的sed或其他命令是什么


使用MacOS。

请尝试以下操作

awk '{for(i=1;i<=NF;i++){gsub(/\/.*\//,"//",$i)}} 1'   Input_file
答案很简单:cat file.txt | sed-e的/\[0-9]\+\/\[0-9]\+\/[0-9]\+\/[1\2/g'>mod.txt

将某些内容放在括号中可以让您在以后引用它,您可以记住第一个斜杠前的数字加上斜杠第一个捕获组,匹配斜杠之间的数字,然后记住斜杠和斜杠第二个捕获组后的任何数字,然后用第一个和第二个捕获组替换整个匹配字符串,抛弃一切


开关g使sed在每次匹配出现时都运行。

使此模式基于sed非常简单:

$ sed 's:/[^/]*/://:g' file
f  1//519 2//2 3//520
f  287//521 1//519 3//520
f  5//522 1//523 287//524
sed 's#/[0-9]*/#//#g' input.txt
这将匹配两个斜杠之间零位或多位的任意长度,并用两个斜杠替换整个捆绑包

在awk中,您可以这样做:

awk '{gsub(/\/[0-9]*\//,"//")} 1' input.txt
gsub命令记录在awk手册页上。末尾的1是打印此行的快捷方式。但您也可以将字段视为实际字段:

awk '{for (i=2;i<=NF;i++) {split($i,a,"/"); $i=sprintf("%s//%s",a[1],a[3])} } 1' input.txt
这在技术上更为正确,因为它将字段视为字段,然后将子字段视为子字段。但它无疑会比其他选项慢,而且还会用OFS作为字段分隔符重写行

最后,您可以单独使用bash,而不使用awk或sed:

shopt -s extglob
while read; do echo "${REPLY//\/+([0-9])\////}"; done < input.txt

这在bash版本3中有效,因为您使用的是macOS。它读取每一行输入,然后使用参数展开进行与前两个选项相同的转换。此解决方案可能比其他解决方案慢。extglob shell选项用于实现更高级的模式。

感谢您的解释。我只是想指出,`awk'{for i=2;iYou's welcome.Yep,如果您的示例输入中有任何行与模式不匹配的话,我肯定会解决这种可能性。不必使用cat和| as sed可以将文件作为参数。例如,sed-i's/regexp/replacement/'文件或sed's/regexp/replacement/'文件>newfile
shopt -s extglob
while read; do echo "${REPLY//\/+([0-9])\////}"; done < input.txt