59 lines
1.1 KiB
Bash
Executable File
59 lines
1.1 KiB
Bash
Executable File
#!/bin/sh
|
|
|
|
_usage () {
|
|
cat<<EOF
|
|
Usage: ${1##*/} [OPTIONS] SEARCH REPLACE [FILES]
|
|
|
|
Replace SEARCH by REPLACE in FILES. If no file is provided, use stdin.
|
|
Backslashes are interpreted in SEARCH and REPLACE (e.g. \n, \t). If you want to
|
|
inhibit this behaviour, you need to double them.
|
|
|
|
Options:
|
|
|
|
-h: Show this help.
|
|
-i: Replace file content instead of printing to stdout.
|
|
|
|
EOF
|
|
}
|
|
|
|
OPT_INPLACE=""
|
|
while getopts ":ih" opt; do
|
|
case $opt in
|
|
i)
|
|
OPT_INPLACE=-i ;;
|
|
h)
|
|
_usage "$0"
|
|
exit 1 ;;
|
|
\?)
|
|
_usage "$0"
|
|
exit 1 ;;
|
|
esac
|
|
done
|
|
|
|
shift $((OPTIND - 1))
|
|
|
|
if [ $# -lt 2 ]; then
|
|
_usage "$0"
|
|
exit 1
|
|
fi
|
|
|
|
search="$1"
|
|
replace="$2"
|
|
shift 2
|
|
|
|
_replace () {
|
|
## We cannot use gsub, otherwise regex substitutions could occur.
|
|
## Source: http://mywiki.wooledge.org/BashFAQ/021
|
|
awk -v s="$search" -v r="$replace" 'BEGIN {l=length(s)} {o="";while (i=index($0, s)) {o=o substr($0,1,i-1) r; $0=substr($0,i+l)} print o $0}' "$@"
|
|
}
|
|
|
|
if [ $# -eq 0 ] || [ -z "$OPT_INPLACE" ]; then
|
|
_replace "$@"
|
|
else
|
|
for i ; do
|
|
out="$(mktemp "$i.XXXXXX")"
|
|
_replace "$i" > "$out"
|
|
mv "$out" "$i"
|
|
done
|
|
fi
|