Linux copy file with another name

How to copy multiple files and rename them at once by appending a string in between the file names in Unix?

I have a few files that I want to copy and rename with the new file names generated by adding a fixed string to each of them. E.g:

ls -ltr | tail -3 games.txt files.sh system.pl 
games_my.txt files_my.sh system_my.pl 
for i in `ls -ltr | tail -10`; do cp $i `echo $i\_my`;done 

2 Answers 2

You can use the following:

for file in * do name="$" extension="$" cp $file $_my$ done 

Note that $ returns the file name without extension, so that from hello.txt you get hello . By doing $_my.txt you then get from hello.txt -> hello_my.txt .

Regarding the extension, extension=»$» gets it. It is based on the question Extract filename and extension in bash.

Sorry, I forgot to mention that the file names are of different extensions and I want to retain the respective extension of each file with the rename.

Thanks. It works. But I don’t exactly get what file%.* and file##*. are doing? What does % and ## do in this case?

$ removes everything before last . , so that you get the extension. $ returns everything before last . , so that you get the file name without extension. You can check gnu.org/software/bash/manual/… for further reference.

If the shell variable expansion mechanisms provided by fedorqui’s answer look too unreadable to you, you also can use the unix tool basename with a second argument to strip off the suffix:

for file in *.txt do cp -i "$file" "$(basename "$file" .txt)_my.txt" done 

Btw, in such cases I always propose to apply the -i option for cp to prevent any unwanted overwrites due to typing errors or similar.

Читайте также:  Установить jupiter notebook linux

It’s also possible to use a direct replacement with shell methods:

Источник

How to copy files recursively, rename them but keep the same extension in Bash?

I have a folder with tens of thousands of different file types. Id like to copy them all to a new folder (Copy1) but also rename them all to $RANDOM but keep the extension intact. I realize I can write a line specifying which extension to find and how to name it, but there is got to be a way to do it dynamically, because there are at least 100 file types and may be more in the future. I have the following so far:

find ./ -name '*.*' -type f -exec bash -c 'cp "$1" "$"' -- <> \; 

but that puts the random number after the extension, and also it puts the all in the same folder. I cant figure out how to do the following 2 things: 1 — Keep all paths intact, but in a new root folder (Copy1) 2 — How to have name be $RANDOM.extension, instead of .extension.$RANDOM PS — by $RANDOM i mean actual randomly generated number. I am interested in keeping folder structure, so we are dealing with a few hundred files at most per directory, but all directories/files need to be renamed to $RANDOM. Another way to look at what I need to do. Copy all contents or Folder1 with all subdirectories and files to Folder2 (where Fodler2 is a $RANDOM name), then rename all folders and files to random names but keep all extensions. EDIT: Ok i figured out how to rename and keep extension. But I have a problem where its dumping all of the files into the root directory where script is run from. How do I keep them in their respective folders? Command Im using is:

find ./ -name '*.*' -type f -exec bash -c 'mv "$1" $RANDOM.$' -- <> \; 

Источник

Читайте также:  Check running programs linux

Copy files with renaming

I have a huge file tree. Some files have same name but in different case, e.g., some_code.c and Some_Code.c . So when I’m trying to copy it to an NTFS/FAT filesystem, it asks me about whether I want it to replace the file or skip it. Is there any way to automatically rename such files, for example, by adding (1) to the name of conflict file (as Windows 7 does)?

Curious. I just wanted to see, what kind of error I get if I try to produce a file with the same name on a NTFS-partition (HPFS/NTFS, according to sudo fdisk -l /dev/sda ), and did touch foo; touch Foo and ended with 2 files foo and Foo . But I’m not curious enogh to reboot into Windows, to look how they look like over there. Migth it just be a FAT-problem? Ah — I have an USB-Stick with FAT, and could create a FAT-system inside a file, . — one moment please. 🙂

3 Answers 3

Many GNU tools such as cp , mv and tar support creating backup files when the target exists. That is, when copying foo to bar , if there is already a file called bar , the existing bar will be renamed, and after the copy bar will contain the contents of foo . By default, bar is renamed to bar~ , but the behavior can be modified:

 # If a file foo exists in the target, then… cp -r --backup source target # rename foo → foo~ cp -r --backup=t source target # rename foo → foo.~1~ (or foo.~2~, etc) 

There are other variants, such as creating numbered backups only when one already exists. See the coreutils manual for more details.

Читайте также:  Драйвера bluetooth linux mint

Brilliant. I didn’t know this option existed, and it just proved to be extremely useful. Thanks @Gilles.

to find possible candidates, and mcopy showed up.

shows a promising option -D clash-option isn’t that cool? But not so cool — it isn’t described. But there are some hints to mtools.dvi, which I searched on my system, without success, and via google, without success, but then, with google, I searched directly for mcopy clash-option and found this site.

to tests for autorename and targetdir a — instead of autorenaming it asked me for every file to ignore or override, that stupid s. .

My version is mtools-4.0.10 and the help page is from 1996 — 15 years old. Should we really lost some features, meanwhile?

I would split the work into two steps:

  • Make a short function, which generates a unique name for a file, if that name is occupied.
  • Run find , and execute that script for every file you wish to copy.

Shall we assist in this approach? 🙂

Here is a script, to autorename files:

#!/bin/bash name=$1 target=$2 autorename () < name=$1 target=$2 no=$3 test -e $/$.$no && autorename $ $ $((no+1)) || cp $ $/$.$no > test -e $/$ && autorename $ $ 0 || cp $ $

and this is my test invocation:

find -maxdepth 1 -name "fo*" -type f -exec ./autorename.sh <> /mnt/hidden/test/a ";" 

Note: -maxdepth, -name and -type where used to restrict the number of affected files dramatically. I didn’t test the script for deeper file structures, nor for blanks in filenames and other, funky characters like linefeed, pagefeed and so on.

I used .1 because it doesn’t make trouble in most commands, while a ( and a ) often need masking.

Источник

Оцените статью
Adblock
detector