LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Linux - Newbie (https://www.linuxquestions.org/questions/linux-newbie-8/)
-   -   Mass file replacement. (https://www.linuxquestions.org/questions/linux-newbie-8/mass-file-replacement-4175471020/)

313 07-26-2013 11:18 AM

Mass file replacement.
 
I'm looking for a way to replace all instances of "aubergine.txt" with a new version of that file with the same name (although it can be different if necessary).

The file is in every folder in my music directory (a few hundred folders), eg. "/music/artist/album/aubergine.txt".

I've tried "sed -i 's/old-word/new-word/g' *.txt" but it doesn't seem to work for replacing large amounts of text.

konsolebox 07-26-2013 12:41 PM

If you have rename from util-linux, you could replace files in the form of rename part_to_replace replacement file1 [file2] ....
With find and xargs you could rename files in one call.
Code:

find -type f -name 'aubergine.txt' -print0 | xargs -0 rename "aubergine" "newname"
Or rename with multiple calls:
Code:

find -type f -name 'aubergine.txt' -exec rename "aubergine" "newname" '{}' \;
Or just rename it through loops and variables with the mv command:
Code:

find -type f -name 'aubergine.txt' -print0 | { IFS=''; while read -rd $'\0' FILE; do mv "$FILE" "${FILE%/*}/newname.txt"; done; }

313 07-26-2013 02:17 PM

Just to confirm, these will actually replace and not just rename the file?

Firerat 07-26-2013 02:19 PM

if the contents of the File are the same, but you have many copies then you should use a symbolic link

save you new file someplace sensible

For this I'm going to use /music/aubergine.txt

Now to create the links

Code:

find /music/*/ -type f -name aubergine.txt -exec ln -sf /music/aubergine.txt {} ';'
all the aubergine.txt files now point to your "master" /music/aubergine.txt
any changes to /music/aubergine.txt ( apart from filename! ) will also be true of the links
Saves space to

-s is create symlink, -f force overwriting existing files/links

313 07-26-2013 02:26 PM

The point is the contents are different, all my folders have a file called 'blah.txt' containing outdated information.

I want to insert a new, completely different 'blah.txt' into every folder with current info.

Also, it's important for various reasons that the files be independent of each folder, not symbolic.

Even a way to bulk remove the old and copy the new file would do the trick.

Firerat 07-26-2013 02:43 PM

Quote:

Originally Posted by 313 (Post 4997447)
The point is the contents are different, all my folders have a file called 'blah.txt' containing outdated information.

do you mean '*.txt'
i.e. couldbeanything.txt

Quote:

Originally Posted by 313 (Post 4997447)
I want to insert a new, completely different 'blah.txt' into every folder with current info.

Also, it's important for various reasons that the files be independent of each folder, not symbolic.

Sorry, from your initial wording I got the impression you wanted to replace all aubergine.txt files with a new aubergine.txt file
Quote:

Originally Posted by 313 (Post 4997447)
Even a way to bulk remove the old and copy the new file would do the trick.

hmm

/path/to/NewTxtFiles/
blah.txt
foo.txt
bar.txt


Like that?


untested
Code:

for File in  /music/*/*/*.txt;do
  echo cp -v /path/to/NewTxtFiles/$(basename $File) $File
done

Will just print the commands
If they look right,
copy'n'paste them ( if only a few )
If *lots*
remove the echo
or
add | sh to the end
e.g. use UpArrow get get last command from history, and just add |sh<enter>

Firerat 07-26-2013 02:59 PM

less noise version

Code:

for File in /path/to/NewTxtFiles/*.txt;do
    find /music/*/ -type f -name "$(basename $File)" -exec echo cp -v $File {} ';'
done

only tries to replace what you want to replace

Ohh, assumes no spaces in filenames

konsolebox 07-26-2013 09:22 PM

The question is, how do you produce this new info? If they are new contents to replace the old contents, where do you get them? If they are files of same name but new contents that would replace (by copying or moving and overwrite, and not creating new) the old ones, where would they come from? Is it necessary to replce the old files with new files or do you intend to just update the information in the old files? Lastly would the new update files would really be of the same name from the old files or would they be new? Please decide about that.

Btw sorry my previous code was meant to rename the files only.

shivaa 07-26-2013 10:07 PM

First rename the new version of file with some other name, let's say newversion.txt, then a simple script can do your job:
Code:

#!/bin/bash
find /music -name 'aubergine.txt' -exec ls {} \; > /tmp/list.txt
while read -r file
do
cat newversion.txt > $file
done < /tmp/list.txt
rm /tmp/list.txt


konsolebox 07-27-2013 03:41 AM

Quote:

Originally Posted by shivaa (Post 4997651)
Code:

#!/bin/bash
find /music -name 'aubergine.txt' -exec ls {} \; > /tmp/list.txt


With process substitution in Bash you could save the use of temporary files.
Code:

while read -r file; do
    cat newversion.txt > $file
done < <(exec find /music -name 'aubergine.txt' -exec ls {} \;)

Also why do you have to add -exec ls {} \;? And quoting may also be a better idea for preventing implementation-variant expansions when spaces on filenames are encountered: "$file".


All times are GMT -5. The time now is 03:11 PM.