-
-
Save hlissner/db74d23fc00bed81ff62 to your computer and use it in GitHub Desktop.
# 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" |
@dennislysenko you need the -0 in both ag and xargs
ag -0 -l $1 | xargs -0 sed -ri.bak -e "s/$1/$2/g"
For what it's worth, this can be added as a function to .bashrc as
function agr { ag -0 -l "$1" | xargs -0 perl -pi.bak -e "s/$1/$2/g"; }
export -f agr
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.
@KevOrr,
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'; }
has typo. Should be:
function agr { ag -0 -l "$1" | AGR_FROM="$1" AGR_TO="$2" xargs -0 perl -pi -e 's/$ENV{AGR_FROM}/$ENV{AGR_TO}/g'; }
.
at least thats what worked for me, I honestly dont know much about the -0
argument.
@ixis-kyle It’s correct, and necessary:
-r, --no-run-if-empty
If the standard input does not contain any nonblanks,
do not run the command. Normally, the command is run
once even if there is no input. This option is a GNU
extension.
(See latest version https://gist.github.com/NightMachinary/719ec06299c65b5216d551658b78c951)
comment() {
}
doc() {
}
function agr {
doc 'usage: from=sth to=another agr [ag-args]'
comment -l --files-with-matches
ag -0 -l "$from" "${@}" | pre-files "$from" "$to"
}
pre-files() {
doc 'stdin should be null-separated list of files that need replacement; $1 the string to replace, $2 the replacement.'
comment '-i backs up original input files with the supplied extension (leave empty for no backup; needed for in-place replacement.)(do not put whitespace between -i and its arg.)'
comment '-r, --no-run-if-empty
If the standard input does not contain any nonblanks,
do not run the command. Normally, the command is run
once even if there is no input. This option is a GNU
extension.'
AGR_FROM="$1" AGR_TO="$2" xargs -r0 perl -pi.pbak -e 's/$ENV{AGR_FROM}/$ENV{AGR_TO}/g'
}
You can use it like this:
from=str1 to=sth agr path1 path2 ...
Supply no paths to make it use the current directory.
Note that ag, xargs, and perl need to be installed and on PATH.
I had to use ag's --nocolor
argument for it go work
This worked well for me:
ag -0 -l 'Old' | xargs -0 sed -ri.bak -e 's/Old/New/g'; git clean -f '**/*.bak';
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'; }
If you add -0 right after xargs, it can also handle files with spaces in the filename ;)