bash sed(或其他)替换前面锚定的双 space 和尾随不可打印字符
bash sed (or others) to substitute front anchored double space AND trailing non-printable character
我有以下形式的行
line=" this is a line with 2 leading spaces and a trailing control char^M"
我想用 ^M 代替 2 个前导空格和尾随控制字符。
echo "${line}" | sed 's/^[[:space:]]*//' | tr -dc '[:print:]'
echo "${line}" | sed 's/^[[:space:]]*//' | sed 's/[^[:print:]]//'
两者都有效。我也试过
echo "${line}" | sed 's/^[[:space:]]*|[^[:print:]]//'
但这不起作用。
为什么最后一个表达式不起作用?
如何通过一次调用 sed 和一个正则表达式来完成此操作?
首选解决方案是什么,例如在效率方面?避免使用许多子外壳会更好吗?
有没有更好的解决方案?
这个单一的 sed 应该可以工作:
sed 's/^[[:blank:]]*//; s/[[:cntrl:]]*$//' <<< "$line"
this is a line with 2 leading spaces and a trailing control char
sed 's/^[[:space:]]*|[^[:print]]//'
不起作用,因为 |
按字面意思匹配自身。 "Or" 在 sed 中拼写为 \|
。 (而 [:print]
应该是 [:print:]
)。
但这还不够,因为默认情况下 sed 只替换第一次出现的;您需要 /g
标志来替换所有出现的地方:
sed 's/^[[:space:]]*\|[^[:print:]]//g'
但是您的原始正则表达式可能会产生一些意想不到的后果:[[:space:]]
匹配换行符,因此如果输入是一个或多个完整的行,它将删除所有空行,而不仅仅是它们的内容。为防止这种情况,请改用 [[:blank:]]
:
sed 's/^[[:blank:]]*\|[^[:print:]]//g'
我有以下形式的行
line=" this is a line with 2 leading spaces and a trailing control char^M"
我想用 ^M 代替 2 个前导空格和尾随控制字符。
echo "${line}" | sed 's/^[[:space:]]*//' | tr -dc '[:print:]'
echo "${line}" | sed 's/^[[:space:]]*//' | sed 's/[^[:print:]]//'
两者都有效。我也试过
echo "${line}" | sed 's/^[[:space:]]*|[^[:print:]]//'
但这不起作用。
为什么最后一个表达式不起作用?
如何通过一次调用 sed 和一个正则表达式来完成此操作?
首选解决方案是什么,例如在效率方面?避免使用许多子外壳会更好吗?
有没有更好的解决方案?
这个单一的 sed 应该可以工作:
sed 's/^[[:blank:]]*//; s/[[:cntrl:]]*$//' <<< "$line"
this is a line with 2 leading spaces and a trailing control char
sed 's/^[[:space:]]*|[^[:print]]//'
不起作用,因为 |
按字面意思匹配自身。 "Or" 在 sed 中拼写为 \|
。 (而 [:print]
应该是 [:print:]
)。
但这还不够,因为默认情况下 sed 只替换第一次出现的;您需要 /g
标志来替换所有出现的地方:
sed 's/^[[:space:]]*\|[^[:print:]]//g'
但是您的原始正则表达式可能会产生一些意想不到的后果:[[:space:]]
匹配换行符,因此如果输入是一个或多个完整的行,它将删除所有空行,而不仅仅是它们的内容。为防止这种情况,请改用 [[:blank:]]
:
sed 's/^[[:blank:]]*\|[^[:print:]]//g'