这是我的问题:
将所有名称以 .jpg 结尾的非隐藏文件(不考虑大小写 - .jpg、.JPG、.JpG 等)从当前工作目录移动到 /tmp。
使用 shell 扩展字符来实现这一点。
Shell 表达式不是我的强项,我不知道该怎么做。有什么建议吗?
答案1
您可以将 shell 模式与[
]
字符类一起使用。
移动每个文件(和文件夹)
- 位于当前工作目录中,和
- 谁的名字不是以 a 开头
.
(即该文件未隐藏),和 - 其名称以
.jpg
或其他七种格变体之一结尾(如.JPG
或.Jpg
)
要/tmp
,您可以使用以下命令:
mv -- *.[Jj][Pp][Gg] /tmp
- 这使用字符类匹配以 结尾的任何文件
.
,然后J
或j
,然后P
或p
,然后G
或g
。字符类(带有[
]
)使用比括号表达式({
}
)更紧凑的语法,并且还有一个好处,即它们只扩展到实际存在的文件的名称,因此即使 的某些大小写变体.jpg
没有出现在任何文件名的末尾,您也不会收到错误消息。(如果不文件匹配。 - 当 shell 扩展模式时,它会默认排除以
.
开头的文件,因此无需执行任何特殊操作即可实现这一点。 - 选项
--
确保mv
将其后的所有内容解释为文件名而不是选项。因此,即使模式匹配名称以 开头的文件-
,它们也将被视为文字文件名而不是 的选项mv
。(这也可以通过在模式前加上 来实现./
,即mv ./*.[Jj][Pp][Gg] /tmp
。)
您可以启用nocaseglob
shell 选项并提供一个简单的模式。
另一种方法是打开nocaseglob
shell 选项,这会导致文件名模式不区分大小写地匹配。由于您可能不需要为后续命令更改此设置,因此您可以将启用nocaseglob
和移动文件的命令括在括号中,以便它们在子 shell 中运行, 以便调用环境不受影响:
(shopt -s nocaseglob; mv -- *.jpg /tmp)
由于jpg
只有三个字符长,您可能更喜欢使用上述字符类方法。但是,对于区分大小写的长单词,设置 会非常方便nocaseglob
。
如果已经存在同名文件会发生什么情况/tmp
?
无论您决定如何指定要移动的文件模式,如果 中已存在与要移动的文件之一同名的文件/tmp
,则将mv
遵循 的默认行为,因为我们没有提供mv
任何有关如何处理冲突的选项。也就是说:
- 如果预先存在的目标文件对于运行的用户具有写权限
mv
,则它将自动且静默地被源文件覆盖。 - 如果运行 的用户对预先存在的目标文件没有写入权限
mv
,则将mv
提示用户并询问该怎么做。(如果用户拥有预先存在的目标文件,则在这种情况下覆盖文件仍可能成功。)
若要在目标文件已存在时指定不同的行为,可以使用--backup
、-b
、-f
、-i
、-n
或-u
选项,如下所述:
答案2
简单的:
mv ./*.{j,J}{p,P}{g,G} /path/to/folder/
或者
mv "$(pwd)"/*.{j,J}{p,P}{g,G} /path/to/folder/