aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/%HOME%/.bash_utils
diff options
context:
space:
mode:
authorEgor Tensin <Egor.Tensin@gmail.com>2017-04-15 09:24:34 +0300
committerEgor Tensin <Egor.Tensin@gmail.com>2017-04-15 09:24:34 +0300
commit35beb4967f15691267fc6438b55e5d27cdb65fda (patch)
treeeca78a9bd0e0b20dbf912b2d5e1f4782f9c25434 /%HOME%/.bash_utils
parentstr_contains, str_*_with: proper escaping (diff)
downloadlinux-home-35beb4967f15691267fc6438b55e5d27cdb65fda.tar.gz
linux-home-35beb4967f15691267fc6438b55e5d27cdb65fda.zip
str_replace*: proper escaping in sed patterns
Diffstat (limited to '%HOME%/.bash_utils')
-rw-r--r--%HOME%/.bash_utils/text.sh53
1 files changed, 46 insertions, 7 deletions
diff --git a/%HOME%/.bash_utils/text.sh b/%HOME%/.bash_utils/text.sh
index f74fb23..0f51b4a 100644
--- a/%HOME%/.bash_utils/text.sh
+++ b/%HOME%/.bash_utils/text.sh
@@ -26,6 +26,39 @@ doslint() {
trim "$@" && trimdoseol "$@" && doseol "$@"
}
+escape_pattern_sed() (
+ set -o errexit -o nounset -o pipefail
+
+ # Only $^*./\[] need to be escaped according to this:
+ # https://unix.stackexchange.com/a/33005/60124
+ local pattern
+ for pattern; do
+ pattern="${pattern//'\'/'\\'}"
+ pattern="${pattern//'/'/'\/'}"
+ pattern="${pattern//'$'/'\$'}"
+ pattern="${pattern//'^'/'\^'}"
+ pattern="${pattern//'*'/'\*'}"
+ pattern="${pattern//'.'/'\.'}"
+ pattern="${pattern//'['/'\['}"
+ pattern="${pattern//']'/'\]'}"
+ pattern="${pattern//$'\n'/'\n'}"
+ echo "$pattern"
+ done
+)
+
+escape_substitution_sed() (
+ set -o errexit -o nounset -o pipefail
+
+ local pattern
+ for pattern; do
+ pattern="${pattern//'\'/'\\'}"
+ pattern="${pattern//'/'/'\/'}"
+ pattern="${pattern//'&'/'\&'}"
+ pattern="${pattern//$'\n'/'\n'}"
+ echo "$pattern"
+ done
+)
+
str_replace() (
set -o errexit -o nounset -o pipefail
@@ -35,8 +68,10 @@ str_replace() (
fi
local old="$1"
+ old="$( escape_pattern_sed "$old" )"
shift
local new="$1"
+ new="$( escape_substitution_sed "$new" )"
shift
sed --binary --in-place -- "s/$old/$new/g" "$@"
@@ -51,8 +86,10 @@ str_replace_word() (
fi
local old="$1"
+ old="$( escape_pattern_sed "$old" )"
shift
local new="$1"
+ new="$( escape_substitution_sed "$new" )"
shift
sed --binary --in-place -- "s/\\b$old\\b/$new/g" "$@"
@@ -63,7 +100,7 @@ str_tolower() (
local s
for s; do
- echo "${s,,}" # | tr '[:upper:]' '[:lower:]'
+ echo "${s,,}"
done
)
@@ -72,13 +109,15 @@ str_toupper() (
local s
for s; do
- echo "${s^^}" # | tr '[:lower:]' '[:upper:]'
+ echo "${s^^}"
done
)
-escape_pattern() {
+escape_pattern_bash() (
set -o errexit -o nounset -o pipefail
+ # Only *?\[] need to be escaped according to:
+ # http://wiki.bash-hackers.org/syntax/pattern#normal_pattern_language
local pattern
for pattern; do
pattern="${pattern//'\'/'\\'}"
@@ -88,7 +127,7 @@ escape_pattern() {
pattern="${pattern//']'/'\]'}"
echo "$pattern"
done
-}
+)
str_contains() (
set -o errexit -o nounset -o pipefail
@@ -102,7 +141,7 @@ str_contains() (
local sub="$2"
[ -z "$sub" ] && return 0
- sub="$( escape_pattern "$sub" )"
+ sub="$( escape_pattern_bash "$sub" )"
test "$str" != "${str#*$sub}"
)
@@ -119,7 +158,7 @@ str_starts_with() (
local sub="$2"
[ -z "$sub" ] && return 0
- sub="$( escape_pattern "$sub" )"
+ sub="$( escape_pattern_bash "$sub" )"
test "$str" != "${str#$sub}"
)
@@ -136,7 +175,7 @@ str_ends_with() (
local sub="$2"
[ -z "$sub" ] && return 0
- sub="$( escape_pattern "$sub" )"
+ sub="$( escape_pattern_bash "$sub" )"
test "$str" != "${str%$sub}"
)