I have a large number of folders with a file named genome.txt
that I need to cp
into the same folder. I am trying to figure out how I can do this so the files look like genome1.txt
, genome2.txt
, etc.. I am looking for a simple solution to this.
Ubuntu – Copy files of same name into same directory
bashcommand linecopyfiles
Related Question
- Ubuntu – Copy files from a directory to a sub-directory (excluding the sub-directory itself)
- Ubuntu – How to copy files with common names and paste them into another folder
- Ubuntu – Rename multiple .txt files changing some characters in specific positions
- Ubuntu – How to copy file from a list to a new folder
Best Answer
Shell script and its usage
This can be done with a simple shell script which makes use of
find ...|while read var ; do ... done
structure ( very common in dealing with filenames ). The bash script below operates on current (top-most) directory and takes single argument for destination.>>>NOTE<<<: script uses
echo
just for testing purposes. When you are satisfied with resulting paths, replaceecho
withmv
to move all filenames orcp
to copy all filenames.Example:
Improving the script for more flexibility
This script can be further improved to make it more general, where user can specify filename , top directory to traverse, and destination all as command-line arguments:
Test run:
Syntax and theory of operation
Over all the script makes use of
command | while read variable ; do ... done
structure. This is a very common approach, and it is frequently used to avoid dealing withls
and difficult filenames that can break scripts.On the left side of the pipe we have
find
command, which takes directory as argument ( and if that's not given, GNUfind
which is used in Linux assumes.
- the current working directory ). The other options include-name
which is the specific filename that we are searching, and-print0
which is used to output results as delimited via non-printable\0
character. It is frequently used to avoid splitting on newline or other characters, because those characters can potentially appear within the filename itself and as a result break the script.On the right side of the pipe we have
while IFS= read -r -d '' ; do . . . done
structure. Thewhile
loop withread
shell built-in is frequently used to realstdin
input, which in this case comes from the pipe.IFS=
-r
and-d ''
are necessary to ensure that we receive filenames safely and recognize that each item is delimited with\0
.The rest of the script is fairly easy. We extract basename of the file using
basename
command. Since in this case we're dealing specifically with known extension and expect to have single dot in the filename, we can use--suffix=".txt"
to strip that part out , leavinggenome
part. We then build new path to file via joining destination , basename, and counter variable. Notice that we use parameter expansion with"${3%/}"
argument (destination folder) in our improved script. This is done to ensure that regardless of whether or not user added/
character at the command-line (./destination
or./destination/
), we extract only bare directory name, and join it via different/
with basename. Notice also thatcounter
variable is not set initially, so the first filename that we receive, will be plaingenome.txt
After than, counter variable will be incremented and thus created and will show up when we deal with other filenames.For more info , please read Filenames and Pathnames in Shell: How to do it Correctly.