Ubuntu: Replace multiple files with one file



Question:

Imagine my directory looked like this:

./original.txt  ./blah.1.txt  ./blah.2.txt  [...]  ./blah.999999.txt  

I essentially want to replace every blah.* file with the contents of original. My initial try was to do this:

$ cp original.txt blah.*  

But I get:

cp: target ``blah.1.txt' is not a directory


Solution:1

Just one more option with tee:

cat original.txt | tee blah.*  

And here's a test case that you can try at home under supervision from a responsible adult:

$ echo "rawr" | tee blah.{1..99}.txt  rawr    $ ls  blah.10.txt  blah.26.txt  blah.41.txt  blah.57.txt  blah.72.txt  blah.88.txt  blah.11.txt  blah.27.txt  blah.42.txt  blah.58.txt  blah.73.txt  blah.89.txt  blah.12.txt  blah.28.txt  blah.43.txt  blah.59.txt  blah.74.txt  blah.8.txt  blah.13.txt  blah.29.txt  blah.44.txt  blah.5.txt   blah.75.txt  blah.90.txt  blah.14.txt  blah.2.txt   blah.45.txt  blah.60.txt  blah.76.txt  blah.91.txt  blah.15.txt  blah.30.txt  blah.46.txt  blah.61.txt  blah.77.txt  blah.92.txt  blah.16.txt  blah.31.txt  blah.47.txt  blah.62.txt  blah.78.txt  blah.93.txt  blah.17.txt  blah.32.txt  blah.48.txt  blah.63.txt  blah.79.txt  blah.94.txt  blah.18.txt  blah.33.txt  blah.49.txt  blah.64.txt  blah.7.txt   blah.95.txt  blah.19.txt  blah.34.txt  blah.4.txt   blah.65.txt  blah.80.txt  blah.96.txt  blah.1.txt   blah.35.txt  blah.50.txt  blah.66.txt  blah.81.txt  blah.97.txt  blah.20.txt  blah.36.txt  blah.51.txt  blah.67.txt  blah.82.txt  blah.98.txt  blah.21.txt  blah.37.txt  blah.52.txt  blah.68.txt  blah.83.txt  blah.99.txt  blah.22.txt  blah.38.txt  blah.53.txt  blah.69.txt  blah.84.txt  blah.9.txt  blah.23.txt  blah.39.txt  blah.54.txt  blah.6.txt   blah.85.txt  blah.24.txt  blah.3.txt   blah.55.txt  blah.70.txt  blah.86.txt  blah.25.txt  blah.40.txt  blah.56.txt  blah.71.txt  blah.87.txt    $ cat blah.67.txt   rawr    $ echo "hooray" > original.txt    $ cat original.txt | tee blah.*.txt  hooray    $ cat blah.67.txt   hooray  


Solution:2

Use bash's for (assuming you're using bash):

for file in blah.*.txt; do      cp original.txt "$file"  done  


Solution:3

You could try this, avoiding for-loops and keeping things in one line:

ls blah.* | xargs -n 1 cp original  

You are getting cp: target blah.1.txt is not a directory in your original attempt, because cp'ing multiple files assumes moving all of them to the directory provided as the last argument. It's simply wrong syntax. Quoting man cp:

SYNOPSIS         cp [OPTION]... [-T] SOURCE DEST         cp [OPTION]... SOURCE... DIRECTORY         cp [OPTION]... -t DIRECTORY SOURCE...    DESCRIPTION         Copy SOURCE to DEST, or multiple SOURCE(s) to DIRECTORY.  

Solely using cp won't help you out. See also this question.


Solution:4

Do this:

for i in `ls *.txt`; do cat original > $i; done  

where original is the text file. cat just dumps the contents and the > pipes the contents into a new file represented by $i (expanded from the list returned by the ls *.txt command)

Note this will completely overwrite those files so you may want to put back them up first in another directory. This will do it for anything with a .txt extension too (including the original file if it is a .txt extension) so you may want to rename things or use a better convention (e.g. blah* instead of *.txt)


Solution:5

Here's another option using find:

find ./ -name 'blah.*.txt' -exec cp original.txt {} \;  

You're asking find to start in the current directory and find files whose name matches the pattern (in quotes, to avoid the shell expanding it and letting find do the pattern-expansion), and for each file found, execute the command between -exec and \;. In this command, {} is replaced by the found file's name.

Look at this answer for a good deal of information on using find effectively:

How can I use find command more efficiently?


Note:If u also have question or solution just comment us below or mail us on toontricks1994@gmail.com
Previous
Next Post »