0

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

2 Answers 2

1

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
3
  • Thanks a lot. It worked perfectly.
    – Harry
    Nov 19, 2023 at 18:21
  • I hope I helped making what you do somewhat understandable, @Harry :) Nov 19, 2023 at 18:51
  • I have tried both solutions, but only the first worked for me. With my limited knowledge, I was only able to understand this solution to some extent. I would probably have to deal with the zsh shell a little more intensively, but I usually don't have the need to do that. Sorry.
    – Harry
    Nov 20, 2023 at 17:59
1

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.

This site is temporarily in read-only mode and not accepting new answers.

Not the answer you're looking for? Browse other questions tagged .