One of the fundamental differences between Windows cmd
and POSIX shells is who is responsible for wildcard expansions. Shells do all the expansions required before starting the actual commands you asked for. cmd
mostly passes the wildcard patterns to the commands unmodified. (I say mostly, since I think there are exceptions, and environment variables are expanded under most circumstances.) This makes writing a rename
that would work with the same syntax as in cmd
quite tricky.
But there is a rename
for Linux - with completely different arguments, check out the man page (which is a bit terse on my system, and rename
comes from the util-linux
package on my system, which should be widely available). Your first rename would be done like this:
rename .txt .bak *.txt
Note that the shell does the *
expansion, so rename
itself actually thinks it was invoked like this:
rename .txt .bak file1.txt file2.txt file3.txt ...
So you can guess the single file version:
rename .txt .bak file1.txt
If you don't want to use rename
but implement this yourself, you could create a function for that. Assuming you only want to change the file extension, and for single-file rename, look at this:
$ function chext() {
newext="$1"
file="$2"
newfile="${file%.*}$newext"
echo mv "$file" "$newfile"
}
$ chext .csv test.txt
mv text.txt text.csv
$newfile
is built using a substring removal to strip out the original extension, then concatenates the new extension. You can extend that function to handle multiple files relatively easily.
As for your ls
question, use the -d
switch. This will prevent ls
from listing the contents of directories.
Demo:
$ ls -al
total 536
drwx------ 3 owner users 528384 Jan 7 17:29 .
drwxr-xr-x 126 owner users 12288 Jan 7 17:26 ..
-rw-r--r-- 1 owner users 0 Jan 7 17:28 f1.csv
-rw-r--r-- 1 owner users 0 Jan 7 17:28 f2.csv
-rw-r--r-- 1 owner users 0 Jan 7 17:28 f3.csv
-rw-r--r-- 1 owner users 0 Jan 7 17:28 f4.csv
drwxr-xr-x 2 owner users 4096 Jan 7 17:33 test
-rw-r--r-- 1 owner users 0 Jan 7 17:27 test.csv
Wildcard rename
$ rename .csv .txt f*
$ ls -al
total 536
drwx------ 3 owner users 528384 Jan 7 17:34 .
drwxr-xr-x 126 owner users 12288 Jan 7 17:26 ..
-rw-r--r-- 1 owner users 0 Jan 7 17:28 f1.txt
-rw-r--r-- 1 owner users 0 Jan 7 17:28 f2.txt
-rw-r--r-- 1 owner users 0 Jan 7 17:28 f3.txt
-rw-r--r-- 1 owner users 0 Jan 7 17:28 f4.txt
drwxr-xr-x 2 owner users 4096 Jan 7 17:33 test
-rw-r--r-- 1 owner users 0 Jan 7 17:27 test.csv
Single-file rename
$ rename .txt .csv f1.txt
$ ls -al
total 536
drwx------ 3 owner users 528384 Jan 7 17:34 .
drwxr-xr-x 126 owner users 12288 Jan 7 17:26 ..
-rw-r--r-- 1 owner users 0 Jan 7 17:28 f1.csv
-rw-r--r-- 1 owner users 0 Jan 7 17:28 f2.txt
-rw-r--r-- 1 owner users 0 Jan 7 17:28 f3.txt
-rw-r--r-- 1 owner users 0 Jan 7 17:28 f4.txt
drwxr-xr-x 2 owner users 4096 Jan 7 17:33 test
-rw-r--r-- 1 owner users 0 Jan 7 17:27 test.csv
The default ls
$ ls -l t*
-rw-r--r-- 1 owner users 0 Jan 7 17:27 test.csv
test:
total 0
-rw-r--r-- 1 owner users 0 Jan 7 17:33 dont_show_me_please
ls
that doesn't inspect directories
$ ls -ld t*
drwxr-xr-x 2 owner users 4096 Jan 7 17:33 test
-rw-r--r-- 1 owner users 0 Jan 7 17:27 test.csv
Best Answer
With GNU
ls
(the version on non-embedded Linux and Cygwin, sometimes also found elsewhere), you can exclude some files when listing a directory.(note the long form of
-I
is--ignore='temp_log.*'
)With zsh, you can let the shell do the filtering. Pass
-d
tols
so as to avoid listing the contents of matched directories.With ksh, bash or zsh, you can use the ksh filtering syntax. In zsh, run
setopt ksh_glob
first. In bash, runshopt -s extglob
first.