Take the 2-minute tour ×
Ask Ubuntu is a question and answer site for Ubuntu users and developers. It's 100% free, no registration required.

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?

share|improve this question

5 Answers 5

up vote 14 down vote accepted

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.

share|improve this answer

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

share|improve this answer
    
for file in path/to/files/!(*.*); do echo mv "$file" "$file.html"; done command renames the directories also. –  Avinash Raj May 22 at 3:24

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.

share|improve this answer

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"}' *
share|improve this answer

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 .

share|improve this answer
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 at 0:11
    
Thats right terdon thank for your comment , but how can i solve this in the same command –  nux May 19 at 0:15
3  
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 at 0:23

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.