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
Try to pass the -n
and -k2
command line options to sort
. I.e.,
find . -maxdepth 1 -type f -iname "*.flac" | sort -n -k2
When I put your unsorted filenames into file 'data.txt' and run this command:
sort -k2 -n data.txt
I get this as output:
./Track 1.flac
./Track 2.flac
./Track 3.flac
./Track 9.flac
./Track 10.flac
./Track 11.flac
explanation of options:
-n (numeric sort) compare according to string numerical value
-k2 means sort on the 2nd field (and to the end of the line),
you could just restrict it to the second field with -k2,2
You didn't ask about this, and I didn't use it above, but it may come in handy some day.
-r reverse sort order
man page for sort
See my related post on SO about sorting according to different fields Sort by third column leaving first and second column intact (in linux) which explains more about the sort command.
Best Answer
Testing: