Search & replace with find & ed

2010-03-28 0 words 0 mins read

Image via Wikipedia

function sr() {

declare pattern replacement name usage
declare -i pvar=0 rvar=0 tvar=0

usage='usage: sr [-t ] [-n name] [-p pattern] [-r replacement] [– ] [dir1 dir2 …]'

# cf. <a href="">

while [[ "${1:0:1}" == '-' ]] ; do

[[ "${1}" == '–' ]] && { shift; break; } # – marks end of options

[[ ${#1} -ne 2 ]] && { echo "${usage}"; return 1; }

case "${1:1:1}" in
'n') name="${2}"
shift 2 ;;
'p') pattern="${2}"
shift 2 ;;
'r') replacement="${2}"
shift 2 ;;
't') tvar=1
shift ;;
*) echo "${usage}"
return 1 ;;


if [[ $pvar -eq 0 ]] || [[ $rvar -eq 0 ]]; then
echo 'Both options -p and -r must be specified!'
echo "${usage}"
return 1

while read -d $'' fpath; do

if [[ -z "$(/usr/bin/egrep -I -m1 '^.' "${fpath}")" ]]; then # skip binary files
echo "<a class="zem_slink freebase/en/binary_file" href="" title="Binary file" rel="wikipedia">Binary file: ${fpath}"

if [[ $tvar -eq 0 ]]; then # perform an actual search & replace

cat «-<a class="zem_slink freebase/en/end-of-file" href="" title="End-of-file" rel="wikipedia">EOF | /bin/ed -s "${fpath}"

else # only simulate a search & replace and print the result to stdout

printf "nn33[1m%s33[mnnn" "${fpath}" # print the current <a class="zem_slink freebase/guid/9202a8c04000641f8000000000220ffa" href="" title="Path (computing)" rel="wikipedia">file path

# delete all lines that do not contain a <a class="zem_slink freebase/en/pattern_matching" href="" title="Pattern matching" rel="wikipedia">pattern match: v/…
# add a final trailing new line in case all lines got deleted: $a…
# do the matching: g/${pattern}/…
# insert '#: ' at the beginning of each line: g/./s/(…

cat «-EOF | /bin/ed -s "${fpath}"

g/${pattern}/s/${pattern}/$(printf "33[32m${replacement}33[m")/g
g/./s/(.*)/#: 1/g


done < <(/usr/bin/find -x "${@}" -type f -name "*${name}" -not -empty -print0)


man ed | less -p '<a class="zem_slink freebase/en/regular_expression" href="" title="Regular expression" rel="wikipedia">REGULAR EXPRESSIONS'

# test mode
sr -t -p hello -r world -n ".txt" /path/to/dir | less -r

# actual search & replace without previous backup
sr -p hello -r world -n ".txt" /path/to/dir

# backslash-escape the / character
sr -t -p '/usr/local' -r '/opt/local' /path/to/file

<a class="zem_slink freebase/en/uniform_resource_locator" href="" title="Uniform Resource Locator" rel="wikipedia">URL: <a href=""><h6 class="zemanta-related-title">Related articles by Zemanta <ul class="zemanta-article-ul"> <li class="zemanta-article-ul-li"><a href="">Guide to Regular Expressions in Java (Part 1) ( <li class="zemanta-article-ul-li"><a href="">Mod and hack the GNome main menu with automated scripts to create a menu of the directory. ( <div class="zemanta-pixie"><a class="zemanta-pixie-a" href="" title="Reblog this post [with Zemanta]"><img class="zemanta-pixie-img" src="" alt="Reblog this post [with Zemanta]" /><span class="zem-script more-related more-info pretty-attribution paragraph-reblog">


Authored By Amit Agarwal

Amit Agarwal, Linux and Photography are my hobbies.Creative Commons Attribution 4.0 International License.

We notice you're using an adblocker. If you like our webite please keep us running by whitelisting this site in your ad blocker. We’re serving quality, related ads only. Thank you!

I've whitelisted your website.

Not now
This website uses cookies to ensure you get the best experience on our website. Learn more Got it