I have a dir with tons of files inside which have been named in malformed such as file..txt
,file2..txt
,etc...
So how to easily remove this second .
from file names?
Any applicable method is appreciated including awk,sed,grep,etc...
Using rename
(as per heemayl's suggestion I narrowed down the globbing only to filenames ending exactly with ..txt
):
rename -n 's/(.*)\./$1/' *..txt
This will match the filename until the last dot and replace the match with everything but the last dot.
If the result is the expected one, remove the -n
option:
rename 's/(.*)\./$1/' *..txt
*
, use *..txt
to get the files as only *
will cause problem when you have any file with only one .
(i mean in general case)
Another rename
variant:
rename 's/\Q.././' *..txt
using \Q
avoids escaping the dots (See http://perldoc.perl.org/perlretut.html)
I have a working solution, still working for better one:
for f in *; do mv $f ${f%.txt}txt; done
Thank to @heemayl note:
Rather than using *, use *..txt to get the files as only * will cause problem when you have any file without . and with only one
So becomes:
for f in *..txt; do mv $f ${f%.txt}txt; done
*
, use *..txt
to get the files as only *
will cause problem when you have any file without .
and with only one .
*
assuming i know file names hierarchy, but you are totally alright in general
You may try the reverse order. This works if the filename contains newline characters.
rename 's/\.([^.]+)$/$1/' *..txt
The very simple way to do this just run the following command inside the directory which contains the filenames in the format u mentioned above
rename 's/\.+txt/\.txt/' *
Filenames can contains a newline character, therefore:
find . -maxdepth 1 -type f -print0 | while read -d $'\0' f; do mv "$f" "${f%.txt}txt"; done
Example
$ find -exec printf "%s ---" {} \;
. ---./foo
..txt ---./foo..txt ---
$ find . -maxdepth 1 -type f -print0 | \
while read -d $'\0' f; do mv "$f" "${f%.txt}txt"; done
$ find -exec printf "%s ---" {} \;
. ---./foo
.txt ---./foo.txt ---
This works quite well if there's no single-dot files:
for file in *; do mv "$file" "${file%%.*}${file#*.}"; done
.\n.
isn't..