Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/regex/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/bash/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Regex 在Bash中替换字符串部分中的字符_Regex_Bash_Awk_Sed - Fatal编程技术网

Regex 在Bash中替换字符串部分中的字符

Regex 在Bash中替换字符串部分中的字符,regex,bash,awk,sed,Regex,Bash,Awk,Sed,我试图将-和:替换为?仅位于中间(第二个)部分,该部分由\uuuuuuuu分隔(3下划线) 输入: aaa___bb-bb:bbb___cc-cc:ccc d-d___d-ddd:d-d___e-e:e 输出: aaa___bb?bb?bbb___cc-cc:ccc d-d___d?ddd?d?d___e-e:e 我尝试了下面的代码 SED命令,但它只替换了在中间部分的 >:的最后一次出现。 echo "aaa___bb-bb:bbb___cc-cc:ccc d-d___d-ddd:d-d_

我试图将
-
替换为
仅位于中间(第二个)部分,该部分由
\uuuuuuuu
分隔(3下划线)

输入:

aaa___bb-bb:bbb___cc-cc:ccc
d-d___d-ddd:d-d___e-e:e
输出:

aaa___bb?bb?bbb___cc-cc:ccc
d-d___d?ddd?d?d___e-e:e

我尝试了下面的代码<代码> SED命令,但它只替换了在

中间部分的<代码> >:的最后一次出现。
echo "aaa___bb-bb:bbb___cc-cc:ccc
d-d___d-ddd:d-d___e-e:e" | sed "s|\(___[^_]*\)[-:]\([^_]*___\)|\1?\2|g"
输出:

aaa___bb-bb?bbb___cc-cc:ccc
d-d___d-ddd:d?d___e-e:e

我不仅限于使用
sed
awk
tr
等也可以使用。

在纯本机bash中,没有外部实用程序:

in='aaa___bb-bb:bbb___cc-cc:ccc
d-d___d-ddd:d-d___e-e:e'

while IFS= read -r line; do
   first=${line%%___*}
   last=${line##*___}
   middle=${line#*___}; middle=${middle%___*}
   printf '%s\n' "${first}___${middle//[-:]/?}___${last}"
done <<<"$in"
in='aaa\uuuuuuuuuBB-bb:bbb\uuuuuuuuuCC-cc:ccc
d-d_uuuud-ddd:d-d_uuuue-e:e'
而IFS=读取-r行;做
first=${line%%\uuuuuu}
last=${line###*.uuuuuu}
中间=${line#*_};middle=${middle%\uuuu*}
printf'%s\n'${first}{uuuuu}{middle/[-:]/?}{uuuuuu}{last}

在纯本地bash中完成,没有外部实用程序:

in='aaa___bb-bb:bbb___cc-cc:ccc
d-d___d-ddd:d-d___e-e:e'

while IFS= read -r line; do
   first=${line%%___*}
   last=${line##*___}
   middle=${line#*___}; middle=${middle%___*}
   printf '%s\n' "${first}___${middle//[-:]/?}___${last}"
done <<<"$in"
in='aaa\uuuuuuuuuBB-bb:bbb\uuuuuuuuuCC-cc:ccc
d-d_uuuud-ddd:d-d_uuuue-e:e'
而IFS=读取-r行;做
first=${line%%\uuuuuu}
last=${line###*.uuuuuu}
中间=${line#*_};middle=${middle%\uuuu*}
printf'%s\n'${first}{uuuuu}{middle/[-:]/?}{uuuuuu}{last}
完成尝试:

尝试:


您与sed解决方案关系密切

sed -r ':a; s/(___.*)[-:](.*___)/\1?\2/; ta' file

条件分支是您只需要的

您已经接近sed解决方案

sed -r ':a; s/(___.*)[-:](.*___)/\1?\2/; ta' file

您只需要条件分支

您的输入来自shell变量吗?档案?小溪?那有关系吗?对于我的脚本,它在一个管道中(grep
grep
的输出)。它有点重要——对于我现有的答案,而不是
(顺便说一句,我认为不必要地使用外部实用程序的人是shell脚本之所以被称为慢的一个重要原因,也就是说,来自systemd的人。当然,bash是一个特别慢的shell,但在shell内部执行任务和为它付出代价之间,至少在什么时候,在性能上仍然有一个数量级的差异对少量数据进行操作。对于一个高效处理大量数据的shell,请考虑KSH9-真正的David Korne,而不是克隆。您的输入来自shell变量?文件?流?这是否重要?对于我的脚本,它在一个管道中(代码< GRP的输出).这有点重要--对于我现有的答案,而不是
(顺便说一句,我认为不必要地使用外部实用程序的人是shell脚本之所以被称为慢的一个重要原因,也就是说,来自systemd的人。当然,bash是一个特别慢的shell,但在shell内部执行任务和为它付出代价之间,至少在什么时候,在性能上仍然有一个数量级的差异对于一个能有效处理大量数据的shell,考虑KSH9-真正的David Korne,而不是克隆。我喜欢这一行,但是,看看性能,@查尔斯解决方案始终花费了一半的时间(28毫秒vs 11MS)。为了完成这项任务,@Sungam,…顺便说一句,如果输入文件足够大(处理很多行),awk会快得多;在这里影响它的是恒定的启动时间。(然而,由于只有两行输入,我实际上期望的差异比2x大得多;看看用于收集这些数字的测试线束并找出它的时间花费在哪里会很有趣。)我喜欢这一行,但是,从性能来看,@Charles solution始终花费了一半的时间(28ms vs 11ms)为了完成这项任务,@Sungam,…顺便说一句,如果输入文件足够大(处理很多行),awk会快得多;在这里影响它的是恒定的启动时间。(然而,由于只有两行输入,我实际上期望的差异比2x大得多;查看用于收集这些数字的测试线束并找出其时间花费在何处会很有趣)。一个更好的优化可能仍然是用一个在同一过程中同时进行模式匹配和替换的工具来替换OP说输入来自的
grep
。我打赌是Awk。一个更好的优化可能仍然是替换OP说输入来自的
grep
在同一过程中同时进行模式匹配和替换的工具。我打赌是Awk。