在 sed 中匹配固定字符串
Match with fixed string in sed
我必须使用sed
来匹配一个固定的字符串。
我在文件中有一个伪数据库,例如:
key\x0value
keyyy\x0value
如果我希望仅在我使用 "key" 而不是 "ey" 作为参数时获得第一行。
* 匹配键:"key"
* 不匹配:"k"、"ke."、"ey"、...:没有正则表达式,没有部分搜索,只有 "key"
我不能使用 awk
并且字符串必须在键的末尾包含 \x0
。
看来我也不能使用 grep,因为它不处理 \x0 或 \0
问题是我不能既要求匹配 /^key\x0/ 又不使用正则表达式解释密钥。
最后,我的脚本将只接受一个参数:要匹配的精确键。
sed
没有匹配固定字符串的工具。但是,可以通过首先转义要匹配的字符串中的所有特殊字符来达到相同的效果。如果将键作为第一个参数提供给此脚本,它将仅打印 file
中包含该键的行:
#!/bin/bash
printf -v script '/^%s\x00/p' "$(sed 's:[]\[^$.*/]:\&:g' <<<"")"
sed -n "$script" file
有关此代码的更多详细信息,请参阅 this answer。
我也遇到了这个问题,上面的答案不充分,实际上是针对 John1024 链接到的答案以获取更多详细信息。它包括空字节,此处不适用。
要匹配固定字符串,您可以使用:
#!/bin/bash
# These can be anything
OUTER_STRING='hello $( string | is [ a ${ crazy } mess ] like wow; end'
INNER_STRING=' $( string | is [ a ${ crazy } mess ] like wow; en'
# This is the meat and potatoes
CLEAN_SED_STRING="$(echo "$INNER_STRING" | sed 's:[]\[^$.*/]:\&:g')"
echo "$OUTER_STRING" | sed "s/$CLEAN_SED_STRING/ worl/"
为了更简洁,我制作了一个 bash 函数,它掩盖了复杂性。在 OSX、CentOS、RHEL6 和 Ubuntu 上测试。它无法处理的只有两个字符是空字符 (\x00) 和换行符 (\x0a)
function substitute {
if [[ "$#" == "2" ]] || [[ "$#" == "3" ]]; then
# Input from stdin
HAYSTACK="$(/bin/cat -)"
NEEDLE=""
NEEDLESUB=""
REGEX_FLAGS=""
else
echo "Usage: echo <HAYSTACK> | substitute <NEEDLE> <NEEDLESUB> [FLAGS]"
echo "Example: echo 'hello w' | substitute 'w' 'world'"
echo "Example: echo 'hello w' | substitute 'O' 'xxxxx' 'gi'"
fi
CLEAN_SED_STRING="$(echo "$NEEDLE" | sed 's:[]\[^$.*/&]:\&:g')"
CLEAN_SED_SUBSTRING="$(echo "$NEEDLESUB" | sed 's:[]\[^$.*/&]:\&:g')"
echo "$HAYSTACK" | sed "s/$CLEAN_SED_STRING/$CLEAN_SED_SUBSTRING/$REGEX_FLAGS"
}
# Simple usage
echo 'Hello Arthur' | substitute 'Arthur' 'World'
# Complex usage
echo '/slashes$dollars[square{curly' | substitute '$dollars[' '[]{}()$$'
# Standard piping
echo '
The ghost said "ooooooOOOOOooooooOOO"
The dog said "bork"
' | substitute 'oo' 'ee'
# With global flag and chaining
echo '
The ghost said "ooooooOOOOOooooooOOO"
The dog said "bork"
' | substitute 'oo' 'ee' 'g' | substitute 'ghost' 'siren'
我必须使用sed
来匹配一个固定的字符串。
我在文件中有一个伪数据库,例如:
key\x0value
keyyy\x0value
如果我希望仅在我使用 "key" 而不是 "ey" 作为参数时获得第一行。 * 匹配键:"key" * 不匹配:"k"、"ke."、"ey"、...:没有正则表达式,没有部分搜索,只有 "key"
我不能使用 awk
并且字符串必须在键的末尾包含 \x0
。
看来我也不能使用 grep,因为它不处理 \x0 或 \0
问题是我不能既要求匹配 /^key\x0/ 又不使用正则表达式解释密钥。
最后,我的脚本将只接受一个参数:要匹配的精确键。
sed
没有匹配固定字符串的工具。但是,可以通过首先转义要匹配的字符串中的所有特殊字符来达到相同的效果。如果将键作为第一个参数提供给此脚本,它将仅打印 file
中包含该键的行:
#!/bin/bash
printf -v script '/^%s\x00/p' "$(sed 's:[]\[^$.*/]:\&:g' <<<"")"
sed -n "$script" file
有关此代码的更多详细信息,请参阅 this answer。
我也遇到了这个问题,上面的答案不充分,实际上是针对 John1024 链接到的答案以获取更多详细信息。它包括空字节,此处不适用。
要匹配固定字符串,您可以使用:
#!/bin/bash
# These can be anything
OUTER_STRING='hello $( string | is [ a ${ crazy } mess ] like wow; end'
INNER_STRING=' $( string | is [ a ${ crazy } mess ] like wow; en'
# This is the meat and potatoes
CLEAN_SED_STRING="$(echo "$INNER_STRING" | sed 's:[]\[^$.*/]:\&:g')"
echo "$OUTER_STRING" | sed "s/$CLEAN_SED_STRING/ worl/"
为了更简洁,我制作了一个 bash 函数,它掩盖了复杂性。在 OSX、CentOS、RHEL6 和 Ubuntu 上测试。它无法处理的只有两个字符是空字符 (\x00) 和换行符 (\x0a)
function substitute {
if [[ "$#" == "2" ]] || [[ "$#" == "3" ]]; then
# Input from stdin
HAYSTACK="$(/bin/cat -)"
NEEDLE=""
NEEDLESUB=""
REGEX_FLAGS=""
else
echo "Usage: echo <HAYSTACK> | substitute <NEEDLE> <NEEDLESUB> [FLAGS]"
echo "Example: echo 'hello w' | substitute 'w' 'world'"
echo "Example: echo 'hello w' | substitute 'O' 'xxxxx' 'gi'"
fi
CLEAN_SED_STRING="$(echo "$NEEDLE" | sed 's:[]\[^$.*/&]:\&:g')"
CLEAN_SED_SUBSTRING="$(echo "$NEEDLESUB" | sed 's:[]\[^$.*/&]:\&:g')"
echo "$HAYSTACK" | sed "s/$CLEAN_SED_STRING/$CLEAN_SED_SUBSTRING/$REGEX_FLAGS"
}
# Simple usage
echo 'Hello Arthur' | substitute 'Arthur' 'World'
# Complex usage
echo '/slashes$dollars[square{curly' | substitute '$dollars[' '[]{}()$$'
# Standard piping
echo '
The ghost said "ooooooOOOOOooooooOOO"
The dog said "bork"
' | substitute 'oo' 'ee'
# With global flag and chaining
echo '
The ghost said "ooooooOOOOOooooooOOO"
The dog said "bork"
' | substitute 'oo' 'ee' 'g' | substitute 'ghost' 'siren'