0

I have a large amount of text files stored on a Red Hat server that contain explicit Windows paths. Today, that path has changed and I would like to change the text files to reflect the new path. As they are Windows paths, they all contain single backslashes. I would like to maintain the single backslashes if possible.

I wanted to ask what the best method to perform this string replacement would be. I have made backups of folders so that I may test on a smaller scale before applying to the larger scale that will affect my group members.

Example:

Change $oldPath to $newPath in all *.py files recursively contained in current directory.

i.e. $oldPath\common\file_referenced should become $newPath\common\file_referenced

brian d foy
  • 129,424
  • 31
  • 207
  • 592
Jake Steele
  • 103
  • 8

1 Answers1

2

Robustly using any awk in any shell on every Unix box and regardless of which characters your old or new directory paths contain and whether or not the final directory in either old or new could be a substring of another existing directory name:

$ cat file
\old\fashioned\common\file_referenced

$ oldPath='\old\fashioned'
$ newPath='\new\fangled\etc'

$ awk '
    BEGIN { old=ARGV[1]; new=ARGV[2]; ARGV[1]=ARGV[2]="" }
    index($0"\\",old"\\")==1 { $0=new substr($0,length(old)+1) }
1' "$oldPath" "$newPath" file
\new\fangled\etc\common\file_referenced

To update all .py files in a directory you could use GNU awk for -i inplace, or you could do for i in *.py; do awk '...' old new "$i" > tmp && mv tmp "$i"; done, or you could use find and/or xargs, etc. - any of the common Unix ways to process multiple files with any command.

Ed Morton
  • 188,023
  • 17
  • 78
  • 185
  • Hi, Ed! Thank you so much -- this is a great answer and I think we're on the right track. That said, it doesn't appear to be properly replacing the old path w/ new path in the files... Any suggestions? For clarity -- ```$oldPath='Z:\...\...\common'``` and $newPath is replacing everything before common in the path (aside from drive letter). Also, we have GNU Awk 4.0.2 on the cluster, and it looks like ```-i inplace``` was added w/ 4.1.0, in case anyone is wondering. I appreciate the ```for i in...``` alternative! – Jake Steele Apr 28 '21 at 15:19
  • As you can see in my answer the code works with the example you provided and there's nothing in your comment to suggest any reason why it wouldn't work for any other input but if you have an example that it doesn't work for then edit your question to show that complete example including old and new values, the input file, and the output file. – Ed Morton Apr 28 '21 at 17:57