I'm trying to perform a recursive search and replace of file content in multiple files.
Given the below in a number of files:
example:{
something: 'ha',
somethingElse: 'ah'
}
I'd like to end up with:
example:{
something: 'ha',
somethingElse: 'ah',
somethingNew: 'ah ha'
}
On Mac OS X, I am trying the following from command line from within a parent directory:
find . -type f -exec perl -p -i -e "s/somethingElse:(.*)/somethingElse:$1,\n\tsomethingNew: 'ah ha'/g" {} \;
It's almost working except the capture group is interpreted as blank resulting in:
example:{
something: 'ha',
somethingElse:,
somethingNew: 'ah ha'
}
What's the problem?
Also not tied to perl
, I don't mind an alternative approach (can use sed
for example)
Thanks to @123 for answer in the comments :
You need to use single quotes. The $1 is interpreted by bash before perl, therefore it is empty when perl sees it. Or just escape it, as you use single quotes in your replacement.
Thus translating to:
find . -type f -exec perl -p -i -e 's/somethingElse:(.*)/somethingElse:$1,\n\tsomethingNew: '\''ah ha'\''/g' {} \;
or:
find . -type f -exec perl -p -i -e "s/somethingElse:(.*)/somethingElse:\$1,\n\tsomethingNew: 'ah ha'/g" {} \;
It might also be wise to add a file extension when doing this, one guess why: you may perform accidentally from too high a directory and corrupt say version control files, ie
find . -type f -name '*.json' -exec perl -p -i -e "s/somethingElse:(.*)/somethingElse:\$1,\n\tsomethingNew: 'ah ha'/g" {} \;
The originally accepted answer which was deleted suggested \\1
rather than $1
. Whilst this worked it was noted as bad practice by other commenters.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.