1

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

4
  • 3
    can it be more than two dots in the file name ?
    – heemayl
    Jul 2, 2015 at 10:31
  • 2
    No, all files have exactly two dots only
    – Maythux
    Jul 2, 2015 at 10:32
  • .\n. isn't ..
    – A.B.
    Jul 2, 2015 at 12:34
  • Not from me. :\
    – A.B.
    Jul 2, 2015 at 13:49

7 Answers 7

5

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
16
  • 1
    no it may happen to have some dots in file name,
    – Maythux
    Jul 2, 2015 at 10:43
  • 1
    kos, Rather than using *, use *..txt to get the files as only * will cause problem when you have any file with only one . (i mean in general case)
    – heemayl
    Jul 2, 2015 at 10:49
  • 2
    Doesn't work with newlines in the filenames
    – A.B.
    Jul 2, 2015 at 10:56
  • 1
    @A.B. Why does this not work when there are new lines in the file name? It looks clean to me (on that issue—there may be other issues to deal with). Jul 2, 2015 at 13:34
  • 1
    already upvoted my friend. ;)
    – A.B.
    Jul 2, 2015 at 14:03
4

Another rename variant:

rename 's/\Q.././' *..txt

using \Q avoids escaping the dots (See http://perldoc.perl.org/perlretut.html)

2
  • And with newlines in a filename? ;)
    – A.B.
    Jul 2, 2015 at 11:36
  • @A.B. it works, you only get a warning about Unsuccessful stat Jul 2, 2015 at 11:39
4

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
3
  • 1
    Rather than using *, use *..txt to get the files as only * will cause problem when you have any file without . and with only one .
    – heemayl
    Jul 2, 2015 at 10:47
  • @heemayl Perfect note, thanks, I just put * assuming i know file names hierarchy, but you are totally alright in general
    – Maythux
    Jul 2, 2015 at 10:48
  • Same here, not with newlines in a filename
    – A.B.
    Jul 2, 2015 at 11:35
2

You may try the reverse order. This works if the filename contains newline characters.

rename 's/\.([^.]+)$/$1/' *..txt
1
  • ya.. you may try rename 's/\.([^.]+)$/$1/s' *..txt also. Jul 2, 2015 at 11:39
2

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/' *
3
  • not for 'foo..bar..txt'
    – A.B.
    Jul 3, 2015 at 11:26
  • @A.B. edited is that fine
    – jerry
    Jul 3, 2015 at 11:30
  • Yes, it works now.
    – A.B.
    Jul 3, 2015 at 11:42
1

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 ---
4
  • @Maythux The ? is a newline char.
    – A.B.
    Jul 2, 2015 at 12:28
  • No, ls shows a ?, I have changed my example.
    – A.B.
    Jul 2, 2015 at 12:31
  • touch "hello?..?txt"
    – Maythux
    Jul 2, 2015 at 12:38
  • @Maythux no, touch "hello<RETURN>..txt"
    – A.B.
    Jul 2, 2015 at 14:01
1

This works quite well if there's no single-dot files:

for file in *; do mv "$file" "${file%%.*}${file#*.}"; done
1
  • No awk version? (already upvoted my friend ;) )
    – A.B.
    Jul 2, 2015 at 14:08

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .