Skip to content

Instantly share code, notes, and snippets.

@hlissner
Last active September 11, 2023 10:14
Show Gist options
  • Star 77 You must be signed in to star a gist
  • Fork 16 You must be signed in to fork a gist
  • Save hlissner/db74d23fc00bed81ff62 to your computer and use it in GitHub Desktop.
Save hlissner/db74d23fc00bed81ff62 to your computer and use it in GitHub Desktop.
Bulk search & replace with ag (the_silver_searcher)
# ag <https://github.com/ggreer/the_silver_searcher>
# usage: ag-replace.sh [search] [replace]
# caveats: will choke if either arguments contain a forward slash
# notes: will back up changed files to *.bak files
ag -0 -l $1 | xargs -0 perl -pi.bak -e "s/$1/$2/g"
# or if you prefer sed's regex syntax:
ag -0 -l $1 | xargs -0 sed -ri.bak -e "s/$1/$2/g"
@devinrhode2
Copy link

devinrhode2 commented Oct 4, 2022

This worked well for me:

ag -0 -l 'Old' | xargs -0 sed -ri.bak -e 's/Old/New/g'; git clean -f '**/*.bak';

@liufeimath
Copy link

Even better so you don't have to worry about slashes:

function agr { ag -0 -l "$1" | AGR_FROM="$1" AGR_TO="$2" xargs -r0 perl -pi -e 's/$ENV{AGR_FROM}/$ENV{AGR_TO}/g'; }

There could be some incompatibilities between the two regex languages though.

I found a way to make this even work for multi-line find-and-replace: add 'BEGIN{undef $/;} ' to the perl -e command and then it'll do multi-line work:
function agr { ag -0 -l "$1" | AGR_FROM="$1" AGR_TO="$2" xargs -r0 perl -pi -e 'BEGIN{undef $/;} s/$ENV{AGR_FROM}/$ENV{AGR_TO}/g'; }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment