How to use sed to change file extensions?

I need to make a sed line (also using channels on Linux) to change the file extension, so I can do something like mv *.1stextension *.2ndextension like mv *.txt *.c . The fact is, I cannot use a batch or for loop, so I have to do all this with the pipe and sed commands.

+2
linux bash sed
03 Oct '13 at 16:59
source share
6 answers

you can use string manipulation

 filename="file.ext1" mv "${filename}" "${filename/%ext1/ext2}" 

Or, if your system supports, you can use rename .

+8
03 Oct '13 at 17:07
source share

sed is for managing the contents of files, not for the file name itself. My suggestion:

 rename 's/\.ext/\.newext/' ./*.ext 

Or is this an existing question that should help.

+5
Oct 03 '13 at 17:54
source share

You can use find to find all the files and then pass them to the while read :

 $ find . -name "*.ext1" -print0 | while read -d $'\0' file do mv $file "${file%.*}.ext2" done 

${file%.*} is a filter with a small right pattern. % indicates the pattern to delete on the right side (the corresponding smallest ball pattern),. .* is the pattern (last . , followed by the characters after . ).

-print0 will split file names with the NUL instead of \n . -d $'\0' will be read in file names separated by the NUL . Thus, file names with spaces, tabs, \n or other stupid characters will be processed correctly.

+2
Oct 03 '13 at 17:23
source share

You can try the following options

Option 1 find along with rename

 find . -type f -name "*.ext1" -exec rename -f 's/\.ext1$/ext2/' {} \; 

Option 2 find along with mv

 find . -type f -name "*.ext1" -exec sh -c 'mv -f $0 ${0%.ext1}.ext2' {} \; 

Note. It is observed that rename does not work for many terminals

+2
Oct 03 '13 at 17:46
source share

Another solution only with sed and sh

 printf "%s\n" *.ext1 | sed "s/'/'\\\\''/g"';s/\(.*\)'ext1'/mv '\''\1'ext1\'' '\''\1'ext2\''/g' | sh 

for better performance: only one process created

 perl -le '($e,$f)=@ARGV;map{$o=$_;s/$e$/$f/;rename$o,$_}<*.$e>' ext2 ext3 
+2
03 Oct '13 at
source share

This may work:

 find . -name "*.txt" | sed -e 's|./||g' | awk '{print "mv",$1, $1"c"}' | sed -e "s|\.txtc|\.c|g" > table; chmod u+x table; ./table 

I do not know why you cannot use a loop. It makes life easier:

 newex="c"; # Give your new extension for file in *.*; # You can replace with *.txt instead of *.* do ex="${file##*.}"; # This retrieves the file extension ne=$(echo "$file" | sed -e "s|$ex|$newex|g"); # Replaces current with the new one echo "$ex";echo "$ne"; mv "$file" "$ne"; done 
+1
Oct 03 '13 at 17:16
source share



All Articles