Linux find change extension

how to change file extensions in a directory [closed]

This question was closed because it is not about an official Ubuntu flavor. It is not currently accepting answers.

This is not about an official Ubuntu flavor. Questions about other Linux distributions can be asked on Unix & Linux, those about Windows on Super User, those about Apple products on Ask Different and generic programming questions on Stack Overflow.

You do realize that these are COPIES of the file ending with .text? (ie. you downloaded the same file 3 times in this case).

Which file should be kept? If you have foo.txt(1) , foo.txt(2) , which one should overwrite the other?

i dont want to overwrite them because i dont have multiple files with same name , i have all the files having different names. i just want to rename foo.txt(1) to foo.txt and foog.txt(2) to foog.txt(just example)

4 Answers 4

Start the one-liner in the folder where the files are saved or change the path for the find command. In the following examples find . the path is . (dot).

find . -type f -print0 | xargs -I<> -0 rename -v -n 's/\(7+\)$//' <> 
find . -type f -print0 | xargs -I<> -0 rename -v 's/\(8+\)$//' <> 

The command finds all files recursively and removes all occurrences of () at the end of the file name.

Remove the $ in ‘s/\(5+\)$//’ to remove all occurrences somewhere in the file name, eg:

find . -type f -print0 | xargs -I<> -0 rename -v 's/\(1+\)//' <> 
% ls -oga -rw-rw-r-- 1 0 Jun 10 09:34 .foo(1) -rw-rw-r-- 1 0 Jun 10 09:34 .bar(2) % find . -type f -print0 | xargs -I<> -0 rename -v 's/\(8+\)$//' <> % ls -aog -rw-rw-r-- 1 0 Jun 10 09:34 .foo -rw-rw-r-- 1 0 Jun 10 09:34 .bar 

Maybe use s/\(1+\)$// to only remove the brackets at the end of the filename. Anyway +1 good solution

it is not working for my directory: -rw-rw-r— 1 DSC02687.JPG(1) -rw-rw-r— 1 DSC02688.JPG(1) [msearch@kaldi vishal]$ find . -type f -print0 | xargs -I<> -0 rename -v ‘s/(2+)$//’ <> [msearch@kaldi vishal]$ ll total 8940 -rw-rw-r— 1 DSC02687.JPG(2) -rw-rw-r— 1 DSC02688.JPG(1)

for i in *.text*; do mv "$i" "$(echo "$i" | sed 's/(9\)$//')"; done 

just need to change the extension (.text or any other extension) according to need.

This will not do recursively..furthermore this is very inefficient way as rename can do it very simply..

#!/usr/bin/env python2 import os, re for root, dirs, files in os.walk('/path/to/directory'): for f in files: oldname = os.path.join(root, f) newname = os.path.join(root, re.search(r'(? 

Considering the first part of file names are different (as you have mentioned it already), so no chance of overwriting.

  • os.walk will traverse all subdirectories under the mentioned directory
  • oldname will contain the name of the file to be changed. os.path.join will add the filename with the directory path by os.path.join
  • newname will contain the name what oldname will be change to. Here we have used the re module to get the file name and then added the filename to the path to directory by os.path.join
  • os.rename will simply rename the files accordingly.
foo ├── 1 spam.text(1) ├── 1.text(23) └── bar ├── 1 egg.text(10) └── 3test.text(5) 
foo ├── 1 spam.text ├── 1.text └── bar ├── 1 egg.text └── 3test.text 

This is "additional comment" and not a complete answer by itself.

This is a really long way of 'explaining' a minor concept - it will appear long and pedantic except if the reader has missed the point.

Short summary:

If there are more than one file of name like foo.txt[(n)]

  • foo.txt, foo.txt(1) -- rename -- > no change
    Appears that nothing happened. It did.
  • foo.txt(1), foo.txt(2) -- rename --> foo.txt, foo.txt(2) (probably)
    One file renamed, one not.

You say that you do not have duplicate files.
You may be correct
BUT - the following is trivially obvious if you know it but a subtle trap if you have not met it before.

As far as the system is concerned

foo.txt = = foo.txt(1) = = foo.txt(2) = etc

regardless of file content or size.

ie If you have two files names foo.txt with or without (n) after them then the system thinks they are duplicates and/or they are duplicates.
Either way, a rename process will fail.

If the rename process would create two files with the same name then it will fail when the attempt is made to create the 1st-duplicate. But

In one case the failure will not create any output so it will appear that "nothing happened" when really "copying failed due to name collision" happened. This case occurs when one file has no (n) suffix and one other has.
eg if existing files are foo.txt and foo.txt(1) then the rename of foo.txt(1) would create a duplicate if allowed so will not occur, and so no action will take place.
foo.txt, foo.txt(1) -> no change

But if existing files are eg foo.txt(1) and foo.txt(2) then the rename of foo.txt(1) would NOT create a duplicate so will occur BUT the rename of foo.txt(2) subsequently would create a duplicate if allowed so no second-file-rename action will take place.
foo.txt(1), foo.txt(2) -> foo.txt, foo.txt(2) (probably)

Источник

How can I change the extension of files of a type using "find" with Bash? [duplicate]

The user inputs a file type they are looking for; it is stored in $arg1 ; the file type they would like to change them is stored as $arg2 . I'm able to find what I'm looking for, but I'm unsure of how to keep the filename the same but just change the type. ie., file1.txt into file1.log .

find . -type f -iname "*.$arg1" -exec mv <> \; 

@Kenavoz The alleged duplicate deals with files in one directory only. I'm pretty sure there is a duplicate somewhere, but I can't find it right now.

4 Answers 4

To enable the full power of shell parameter expansions, you can call bash -c in your exec action:

find . -type f -iname "*.$arg1" \ -exec bash -c 'echo mv "$1" "$"' _ <> "$arg2" \; 

We add <> and "$arg2" as a parameters to bash -c , so they become accessible within the command as $0 and $1 . $ removes the extension, to be replaced by whatever $arg2 expands to.

As it is, the command just prints the mv commands it would execute; to actually rename the files, the echo has to be removed.

The quoting is relevant: the argument to bash -c is in single quotes to prevent $0 and $1 from being expanded prematurely, and the two arguments to mv , and arg2 are also quoted to deal with file names with spaces in them.

Could there be ref. to what the _ is in this case? is it this parameter from the shell expansions page?

Combining the find -exec bash idea with the bash loop idea, you can use the + terminator on the -exec to tell find to pass multiple filenames to a single invocation of the bash command. Pass the new type as the first argument - which shows up in $0 and so is conveniently skipped by a for loop over the rest of the command-line arguments - and you have a pretty efficient solution:

find . -type f -iname "*.$arg1" -exec bash -c \ 'for arg; do mv "$arg" "$.$0"; done' "$arg2" <> + 

Alternatively, if you have either version of the Linux rename command, you can use that. The Perl one (a.k.a. prename , installed by default on Ubuntu and other Debian-based distributions; also available for OS X from Homebrew via brew install rename ) can be used like this:

find . -type f -iname "*.$arg1" -exec rename 's/\Q'"$arg1"'\E$/'"$arg2"'/' <> + 

That looks a bit ugly, but it's really just the s/old/new/ substitution command familiar from many UNIX tools. The \Q and \E around $arg1 keep any weird characters inside the suffix from being interpreted as regular expression metacharacters that might match something unexpected; the $ after the \E makes sure the pattern only matches at the end of the filename.

The pattern-based version installed by default on Red Hat-based Linux distros (Fedora, CentOS, etc) is simpler:

find . -type f -iname "*.$arg1" -exec rename ".$arg1" ".$arg2" <> + 

but it's also dumber: if you rename .com .exe stackoverflow.com_scanner.com , you'll get a file named stackoverflow.exe_scanner.exe .

Источник

Linux/Cygwin recursively copy file change extension [closed]

I'm looking for a way to recursively find files with extension X (.js) and make a copy of the file in the same directory with extension Y (.ts). e.g. /foo/bar/foobar.js --> /foo/bar/foobar.js and /foo/bar/foobar.ts /foo/bar.js --> /foo/bar.js and /foo/bar.ts etc etc My due diligence: I was thinking of using find & xargs & cp and brace expansion ( cp foobar. ) but xargs uses the braces to denote the list of files passed from xargs. This makes me sad as I just recently discovered the awesome-sauce that is brace expansion/substitution. I feel like there has to be a one-line solution but I'm struggling to come up with one. I've found ideas for performing the task: copying the desired to a new directory and then merging this directory with the new one; recursively run a renaming script in each directory; copy using rsync; use find, xargs and cpio. As it stands it appears that running a renaming script script like this is what I'll end up doing.

xargs does not interpret <> specially. How do you want to get just foobar from foobar.js in xargs, though?

I have used <> for the argument list in xargs. I guess I assumed that was the way to do it. Ooops. Regardless, if there is a way to perform some sed/awk/bash magic on the argument list passed to xargs to get the desired name change I'd be happy. I'm assuming that @choroba doesn't know how either?

1 Answer 1

find . -name "*.js" -exec bash -c 'name="<>"; cp "$name" "$.ts"' \; 

Using find , you can execute a command directly on a file that you've found, by using the -exec option; you don't need to pipe it through xargs. It takes the command name followed by arguments to the command, followed by a single argument ; , which you have to escape to avoid the shell interpreting it. find will replace any occurrence of <> in the command name or arguments with the file found.

In order call a command with the appropriate ending substituted, there are multiple approaches you can take, but a simple one is to use Bash's parameter expansion. You need to define a shell parameter that contains the name (in this case, I creatively chose name=<> ), and then you can use parameter expansion on it. $ strips off suffix from the value of $variable ; I then add on .ts to the end, and have the name I'm looking for.

Источник

Читайте также:  Стандартные обои linux mint
Оцените статью
Adblock
detector