简体   繁体   中英

Search and replace unix command line, perl capture group empty

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM