Using grep and sed to find and replace a string

后端 未结 8 1761
耶瑟儿~
耶瑟儿~ 2020-11-30 18:41

I am using the following to search a directory recursively for specific string and replace it with another:

grep -rl oldstr path | xargs sed -i \'s/oldstr/ne         


        
相关标签:
8条回答
  • 2020-11-30 19:11

    My use case was I wanted to replace foo:/Drive_Letter with foo:/bar/baz/xyz In my case I was able to do it with the following code. I was in the same directory location where there were bulk of files.

    find . -name "*.library" -print0 | xargs -0 sed -i '' -e 's/foo:\/Drive_Letter:/foo:\/bar\/baz\/xyz/g'
    

    hope that helped.

    0 讨论(0)
  • Your solution is ok. only try it in this way:

    files=$(grep -rl oldstr path) && echo $files | xargs sed....
    

    so execute the xargs only when grep return 0, e.g. when found the string in some files.

    0 讨论(0)
  • 2020-11-30 19:23

    Standard xargs has no good way to do it; you're better off using find -exec as someone else suggested, or wrap the sed in a script which does nothing if there are no arguments. GNU xargs has the --no-run-if-empty option, and BSD / OS X xargs has the -L option which looks like it should do something similar.

    0 讨论(0)
  • 2020-11-30 19:26

    You can use find and -exec directly into sed rather than first locating oldstr with grep. It's maybe a bit less efficient, but that might not be important. This way, the sed replacement is executed over all files listed by find, but if oldstr isn't there it obviously won't operate on it.

    find /path -type f -exec sed -i 's/oldstr/newstr/g' {} \;
    
    0 讨论(0)
  • 2020-11-30 19:33

    I have taken Vlad's idea and changed it a little bit. Instead of

    grep -rl oldstr path | xargs sed -i 's/oldstr/newstr/g' /dev/null
    

    Which yields

    sed: couldn't edit /dev/null: not a regular file
    

    I'm doing in 3 different connections to the remote server

    touch deleteme
    grep -rl oldstr path | xargs sed -i 's/oldstr/newstr/g' ./deleteme
    rm deleteme
    

    Although this is less elegant and requires 2 more connections to the server (maybe there's a way to do it all in one line) it does the job efficiently as well

    0 讨论(0)
  • 2020-11-30 19:33

    If you are to replace a fixed string or some pattern, I would also like to add the bash builtin pattern string replacement variable substitution construct. Instead of describing it myself, I am quoting the section from the bash manual:

    ${parameter/pattern/string}

    The pattern is expanded to produce a pattern just as in pathname expansion. parameter is expanded and the longest match of pattern against its value is replaced with string. If pattern begins with /, all matches of pattern are replaced with string. Normally only the first match is replaced. If pattern begins with #, it must match at the beginning of the expanded value of parameter. If pattern begins with %, it must match at the end of the expanded value of parameter. If string is null, matches of pattern are deleted and the / following pattern may be omitted. If parameter is @ or *, the substitution operation is applied to each positional parameter in turn, and the expansion is the resultant list. If parameter is an array variable subscripted with @ or *, the substitution operation is applied to each member of the array in turn, and the expansion is the resultant list.

    0 讨论(0)
提交回复
热议问题