使用 sed 将每个字符替换为自身后跟 $n 次的字符?
Use sed to replace every character by itself followed by $n times a char?
我正在尝试 运行 下面的命令将 DECEMBER 中的每个字符替换为本身后跟 $n 问号。我试过像 {$n} 这样转义 {$n} 并保持原样。然而我的输出一直是 D?{$n}E?{$n}...难道用 sed 就不可能做到这一点吗?
我怎么知道这个。
echo 'DECEMBER' > a.txt
sed -i "s%\(.\)%\(?\){$n}%g" a.txt
cat a.txt
范围(也称为区间或限制量词),如 {3}
/ {3,}
/ {3,6}
,是 regex 的一部分,并且不是 替换 模式。
您可以使用
sed -i "s/./&$(for i in {1..7}; do echo -n '?'; done)/g" a.txt
#!/bin/bash
sed "s/./&$(for i in {1..7}; do echo -n '?'; done)/g" <<< "DECEMBER"
# => D???????E???????C???????E???????M???????B???????E???????R???????
这里,.
匹配任何字符,替换模式中的 &
将它放回去,$(for i in {1..7}; do echo -n '?'; done)
在它后面添加七个问号。
这可能适合您 (GNU sed):
n=5
sed -E ':a;s/[^\n]/&\n/g;x;s/^/x/;/x{'"$n"'}/{z;x;y/\n/?/;b};x;ba' file
将换行符附加到一行中的每个非换行符 $n
次,然后用预期字符替换所有换行符 ?
。
N.B。换行符被选为初始替换字符,因为它不可能位于一行内(sed 使用换行符分隔行),如果当前行中已经存在最终替换字符,则替换是正确的。
在设置 n=2
后,在每个 Unix 机器上的任何 shell 中有效地使用任何 awk:
$ awk -v n="$n" '
BEGIN {
new = sprintf("%*s",n,"")
gsub(/./,"?",new)
}
{
gsub(/./,"&"new)
print
}
' a.txt
D??E??C??E??M??B??E??R??
要“就地”进行更改,请将 GNU awk 与 -i inplace
一起使用,就像 GNU sed 具有 -i
.
警告 - 如果您要在替换文本中使用的字符是 &
那么您需要在 BEGIN 部分使用 gsub(/./,"\\\&",new)
以使其被视为文字而不是反向引用元字符。使用任何 sed 解决方案和任何在脚本周围使用双引号的解决方案在处理 $
时都会遇到更多问题(例如处理 </code> 或 <code>/
)具有 shell 扩展未加引号的脚本的解决方案在通配字符方面会有更多问题。
这条单线应该可以解决问题:
sed 's/./&'$(printf '%*s' "$n" '' | tr ' ' '?')'/g' a.txt
假设 $n
扩展为正整数并且命令在 POSIX shell.
中执行
我正在尝试 运行 下面的命令将 DECEMBER 中的每个字符替换为本身后跟 $n 问号。我试过像 {$n} 这样转义 {$n} 并保持原样。然而我的输出一直是 D?{$n}E?{$n}...难道用 sed 就不可能做到这一点吗?
我怎么知道这个。
echo 'DECEMBER' > a.txt
sed -i "s%\(.\)%\(?\){$n}%g" a.txt
cat a.txt
范围(也称为区间或限制量词),如 {3}
/ {3,}
/ {3,6}
,是 regex 的一部分,并且不是 替换 模式。
您可以使用
sed -i "s/./&$(for i in {1..7}; do echo -n '?'; done)/g" a.txt
#!/bin/bash
sed "s/./&$(for i in {1..7}; do echo -n '?'; done)/g" <<< "DECEMBER"
# => D???????E???????C???????E???????M???????B???????E???????R???????
这里,.
匹配任何字符,替换模式中的 &
将它放回去,$(for i in {1..7}; do echo -n '?'; done)
在它后面添加七个问号。
这可能适合您 (GNU sed):
n=5
sed -E ':a;s/[^\n]/&\n/g;x;s/^/x/;/x{'"$n"'}/{z;x;y/\n/?/;b};x;ba' file
将换行符附加到一行中的每个非换行符 $n
次,然后用预期字符替换所有换行符 ?
。
N.B。换行符被选为初始替换字符,因为它不可能位于一行内(sed 使用换行符分隔行),如果当前行中已经存在最终替换字符,则替换是正确的。
在设置 n=2
后,在每个 Unix 机器上的任何 shell 中有效地使用任何 awk:
$ awk -v n="$n" '
BEGIN {
new = sprintf("%*s",n,"")
gsub(/./,"?",new)
}
{
gsub(/./,"&"new)
print
}
' a.txt
D??E??C??E??M??B??E??R??
要“就地”进行更改,请将 GNU awk 与 -i inplace
一起使用,就像 GNU sed 具有 -i
.
警告 - 如果您要在替换文本中使用的字符是 &
那么您需要在 BEGIN 部分使用 gsub(/./,"\\\&",new)
以使其被视为文字而不是反向引用元字符。使用任何 sed 解决方案和任何在脚本周围使用双引号的解决方案在处理 $
时都会遇到更多问题(例如处理 </code> 或 <code>/
)具有 shell 扩展未加引号的脚本的解决方案在通配字符方面会有更多问题。
这条单线应该可以解决问题:
sed 's/./&'$(printf '%*s' "$n" '' | tr ' ' '?')'/g' a.txt
假设 $n
扩展为正整数并且命令在 POSIX shell.