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
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
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.