Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Restore multiple backup files created with find followed by sed

Tags:

grep

find

sed

xargs

I need to edit files with specific pattern in their names. These files are spread across multiple hierarchical directories.

I am using find followed by sed with the help of xargs to achieve the same as follows:

find . -type f -name "file*" | sed -i.bak 's/word1/replace_word1/g'

My problem is that now I want to revert back the changes from backup files (*.bak). Sample directory tree will look like as shown below. I am looking for linux command (may be a chain) to achieve the same.

$ tree
.
|-- pdir1
|   |-- dir1
|   |   |-- dir2
|   |   |   |-- file2
|   |   |   `-- file2.bak
|   |   |-- file1
|   |   `-- file1.bak
|   `-- dir3
|       |-- file3
|       `-- file3.bak
`-- pdir2
    |-- file1
    `-- file1.bak

I can find all backup files using following find command. But can't figure out what to do next. It would be appreciable if your could help me solve this.

find . -type f -name "file*.bak"

Note

I observe this problem as general scenario. I had faced this many times but got away with writing a small wrapper script for it. Here I am hoping for a generic and concise solution.

like image 501
jkshah Avatar asked Mar 23 '23 06:03

jkshah


2 Answers

One option could be use rename with find:

find . -type f -name "*.bak" -exec rename 's/\.bak$//' {} \;

This would not rename foo.bak if foo exists. In order to force overwriting, use the -f option for rename:

find . -type f -name "*.bak" -exec rename -f 's/\.bak$//' {} \;

EDIT: If you can't use rename, try:

find . -name "*.bak" -exec sh -c 'mv -f $0 ${0%.bak}' {} \;

Explanation of the above (last) command: For each result returned by find, a shell command is invoked that takes the result as a parameter (denoted by {}) for mv -f $0 ${0%.bak}. $0 is a positional parameter and ${0%.bak} denotes shell parameter expansion for removing .bak from the end of the parameter. In effect, for a result foo.bak, the shell would issue a command mv -f foo.bak foo.

like image 143
devnull Avatar answered Apr 25 '23 05:04

devnull


You can restore simply with a for loop that traverse directories. It doesn't check if the file without the bak extension exists.

for f in **/*.bak; do mv -- "$f" "${f%.bak}"; done
like image 27
Birei Avatar answered Apr 25 '23 03:04

Birei