9

Given the following files:

english_api
english_overview
style.css

I want to get:

english_api.html
english_overview.html
style.css

In other words how to append a text to all files that do Not Contain a dot (.) within a directory using terminal.

Obviously there is a lot of files in that folder; I just wrote 3 as an example.

If I were to, lets say, replace .css with .html in that folder, I would use:

rename .css .html *.css

But I cannot really think of a way to match files that do not contain something. Also how to append (vs replace) using rename command?

5 Answers 5

13

Try this find command,

find . -type f ! -name "*.*" -exec mv {} {}.html \;

It renames the files which doesn't contain dots in their filenames present in the current directory to this filename.htmlformat(added .html at the last).

. --> Represents current directory

-type f --> To do this operation only on files.

! -name "*.*" --> print the name of the files which doesn't have dots in their name.

-exec mv {} {}.html --> find command perform this move(or)rename operation on the extracted filenames.

\; --> Represents the end of find command.

6

In bash, you could use extended shell globs e.g.

for file in path/to/files/!(*.*); do echo mv "$file" "$file.html"; done

(remove the echo once you've confirmed it is matching the correct pattern). If extended globbing is not already enabled, you can enable it with shopt -s extglob.

Another option is using the perl-based rename function with a regex that excludes literal .

rename -nv 's/^[^.]+$/$&.html/' path/to/files/*

(remove the n option once you have confirmed it is matching the correct pattern).

1
  • 1
    for file in path/to/files/!(*.*); do echo mv "$file" "$file.html"; done command renames the directories also. May 22, 2014 at 3:24
2

My prefered in cases like this is mmv. It is not installed by default in Ubuntu, but you can install using sudo apt-get install mmv command.

In your case you need to use it two times:

  1. Rename all files from current directory by adding .html at the end of each file name:

    mmv -v '*' '#1.html'
    
  2. Rename again (back) all files which had previously in their names one or more . (dots):

    mmv -v '*.*.html' '#1.#2'
    

Or, in one line:

mmv -v '*' '#1.html' && mmv -v '*.*.html' '#1.#2'

-v option is not mandatory. I use it only for a verbose output because without it mmv performs actions silently.

See man mmv for more info.

1

With the Perl rename command (prename), you can add a condition that the file name must contain a dot. If the Perl snippet doesn't change the name of a file, that file is left untouched. Here are a few ways to write this:

prename '/\./ or s/$/.html/' *
prename 's/$/.html/ unless /\./' *
prename '$_ .= ".html" unless /\./' *
prename '$_ = "$_.html" unless /\./' *
prename 'if (!/\./) {$_ = "$_.html"}' *
-2

The answers are perfect , i also give you another command that do this job :

ls -1 | grep -v "\." | awk '{print "mv "$0" "$0".html"}' | sh

Some explanation :

ls - list directory contents

 -1     list one file per line

grep prints the matching lines.

-v, --invert-match
              Invert the sense of matching, to select non-matching lines.  (-v
              is specified by POSIX.)

Awk is mostly used for pattern scanning and processing. It searches one or more files to see if they contain lines that matches with the specified patterns and then perform associated actions.

NOTE :

I try your scenario and the command make the job .

3
  • 6
    This fails on file names that contain any type of whitespace (spaces, tabs, newlines etc.). As a general rule, you should never parse ls.
    – terdon
    May 19, 2014 at 0:11
  • Thats right terdon thank for your comment , but how can i solve this in the same command
    – nux
    May 19, 2014 at 0:15
  • 4
    You can't really. There is almost no safe way to parse ls. If you really want to do it using awk and sh, try something like printf "'%s'\n" -- !(*.*) | awk '{print "mv -- "$0" "$0".html"}' | sh. That will still break on file names with newlines but at least it can deal with spaces. The -- is needed for cases where you have file names beginning with -.
    – terdon
    May 19, 2014 at 0:23

You must log in to answer this question.

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