I'd like to batch copy files in an special way – Do I need a script?

I’ve been using Linux for a few years now, but I’m not very familiar with the console. I can manage simple copy commands, but now I have a requirement that is beyond my knowledge.

I have a large number of directories (folder1, folder2, folder3 etc.). In each of these directories there is a file with the same name (e.g. file.txt). I would now like to batch copy these files within the directories and use the names of the respective directory as the file name. The original files should remain unchanged.

So… ‘folder1/file.txt’ is to be copied to ‘folder1/folder1.txt’.

This means that there should be two files with the same content in each directory, one of which has the same name as the directory.

I assume I need a bash script for the operation, right? And if so, what would this script look like?

I’d appreciate any help.

Harry

Asked By: Harry

||

Yes, you’d need a script (or something equivalently complex when using other programs). But it will not be long nor hard to understand:

#/------------------------------ for … in … : go through the list supplied after
#|                               the "in" one by one, setting the variable
#|                               specified after the "for" to each element from
#|                               the list, in turn
#| 
#|      /----------------------- original: name of variable to set to each value
#|      |
#|      |           /----------- */file.txt: the list of all "foldername/file.txt"
#|      |           |
#|  /------    /--------   
for original in */file.txt ; do

  folder_only="${original%/file.txt}"
  #--------/  -------------------/
  #    |                 |
  #    |                 ------------ become the value of "original", but cut off
  #    |                               any "/file.txt" from the end; for example:
  #    |                               "folder1/file.txt" becomes "folder1"
  #    |
  #    ------------------------------ save the result in a variable that's called
  #                                    "folder_only"

  cp -- "${original}" "${folder_only}/${folder_only}.txt"
done

or, without the explanations:

for original in */file.txt ; do
  folder_only="${original%/file.txt}"
  cp -- "${original}" "${folder_only}/${folder_only}.txt"
done
Answered By: Marcus Müller

Doing batch-renaming or copying is a lot easier when you use the zsh shell instead of bash as it comes with a very powerful autoloadable function called zmv:

autoload -Uz zmv # best in your ~/.zshrc
zmv -C '(folder<->)/file.txt' '$1/$1.txt'

Where folder<-> matches on folder followed by any sequence of ASCII decimal digits. Replace with just * if the folder names don’t have to follow the folder<digits> pattern.

Answered By: Stéphane Chazelas
Categories: Answers Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.