如何在 ls 和 mv 中使用 ms-dos 样式的通配符?

cwd*_*cwd 9 linux command-line ls rename

我有一个来自 MS-DOS 背景的不幸——但至少它让我意识到 Linux 是多么强大。我一直在努力让我的 Linux-Fu 达到标准,但有几件事可以用 DOS 完成,我不确定如何用 Linux最容易地完成:

重命名多个文件 - 使用两个通配符

c:\> dir

Directory of c:\
    file1.txt
    file2.txt
    file3.txt
    file4.txt

c:\>rename *.txt *.bak

c:\> dir

Directory of c:\
    file1.bak
    file2.bak
    file3.bak
    file4.bak
Run Code Online (Sandbox Code Playgroud)

我知道我可以find -exec在这里使用,但可以使用更短的语法——也许mv带有一些特殊的标志或语法?我想这的关键是第二个 *通配符,因为 linux 对第一个通配符应该没有问题(即我知道如何选择我想使用通配符重命名的文件)

重命名单个文件 - 使用一个通配符

c:\> dir

Directory of c:\
    file1.txt

c:\>rename file1.txt *.bak

c:\> dir

Directory of c:\
    file1.bak
Run Code Online (Sandbox Code Playgroud)

这在重命名长而笨重的文件名时特别有用。我想也许我可以用它mv file1.txt $1.bak来结束,file1.txt.bak这也是可以接受的,但我不确定您是否可以$1使用 shell 命令引用内联参数。同样在这种特殊情况下,ms-dos 如何将*通配符混为一谈以用作文件名的一部分的一种捕获/替换匹配,这很方便。

使用通配符过滤目录列表

c:\> dir

Directory of c:\
    file1.txt
    file2.txt
    file3.txt
    file4.txt
    text.txt
    \temp       (directory) 

c:\> dir file*

Directory of c:\
    file1.txt
    file2.txt
    file3.txt
    file4.txt

c:\> t*

Directory of c:\
    text.txt
    \temp       (directory) 
Run Code Online (Sandbox Code Playgroud)

我不确定这样做的正确语法是什么ls,或者是否可能。如果我做了类似的事情,ls t*它会递归到以t. 我的解决方法一直在使用find . --max-depth 1 -iname "t*"或类似的东西ls -al | grep t- 两者都不像现在那么简短dir t*

最后,我知道我可以设置别名来缩短这些长命令,但我想学习一些开箱即用的 linux-fu 来做这些事情,因为有时你连接到远程系统或工作在新机器上。

所以,我怎么能mvls文件相同的方式,我曾经dirrename文件?

Mat*_*Mat 15

Windowscmd和 POSIX shell之间的根本区别之一是谁负责通配符扩展。在启动您要求的实际命令之前,Shell 会执行所有所需的扩展。cmd 大多数情况下将通配符模式传递给未修改的命令。(我说的主要是,因为我认为有例外,并且在大多数情况下环境变量会被扩展。)这使得编写一个rename使用与 in 相同的语法cmd非常棘手。

但是有一个rename适用于 Linux - 有完全不同的参数,请查看手册页(在我的系统上有点简洁,rename来自util-linux我系统上的包,应该可以广泛使用)。您的第一次重命名将是这样完成的:

rename .txt .bak *.txt
Run Code Online (Sandbox Code Playgroud)

请注意,shell 进行了*扩展,因此rename它本身实际上认为它是这样调用的:

rename .txt .bak file1.txt file2.txt file3.txt ...
Run Code Online (Sandbox Code Playgroud)

所以你可以猜测单个文件版本:

rename .txt .bak file1.txt
Run Code Online (Sandbox Code Playgroud)

如果您不想使用rename但自己实现它,您可以为此创建一个函数。假设您只想更改文件扩展名,并且对于单个文件重命名,请查看:

rename .txt .bak *.txt
Run Code Online (Sandbox Code Playgroud)

$newfile使用子字符串删除来删除原始扩展名,然后连接新扩展名。您可以扩展该功能以相对轻松地处理多个文件。


至于你的ls问题,使用-d开关。这将阻止ls列出目录的内容。

演示:

$ 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
Run Code Online (Sandbox Code Playgroud)

通配符重命名

$ 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
Run Code Online (Sandbox Code Playgroud)

单文件重命名

$ 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
Run Code Online (Sandbox Code Playgroud)

默认的 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
Run Code Online (Sandbox Code Playgroud)

ls 不检查目录

$ 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
Run Code Online (Sandbox Code Playgroud)