如何在bash中使用通配符更改文件名

如何在bash中使用通配符更改文件名,bash,wildcard,cp,mv,Bash,Wildcard,Cp,Mv,所以我的具体问题是我下载了一些MP3专辑,它们的标题中没有曲目编号,所以它们默认为字母排序,这显然是不理想的。我希望能够使用终端命令快速重命名它们,在终端命令中,我使用通配符对绒毛进行排序。因此,我从几个角度尝试了这一点,但没有成功,我需要一些指导 一方面,我想尝试类似于mv*someSongN*01-{reference original name here}。在mv的第二个参数中,我不清楚如何引用原始文件名,但前面有一个01- 我尝试的另一个方法是创建一个临时bash变量,后跟一个mv命令。

所以我的具体问题是我下载了一些MP3专辑,它们的标题中没有曲目编号,所以它们默认为字母排序,这显然是不理想的。我希望能够使用终端命令快速重命名它们,在终端命令中,我使用通配符对绒毛进行排序。因此,我从几个角度尝试了这一点,但没有成功,我需要一些指导

一方面,我想尝试类似于
mv*someSongN*01-{reference original name here}
。在
mv
的第二个参数中,我不清楚如何引用原始文件名,但前面有一个
01-


我尝试的另一个方法是创建一个临时bash变量,后跟一个
mv
命令。我通过创建一个没有任何扩展名的测试文件--
touch test
对此进行了测试。我发现
echo
mv
对通配符的处理方式不同。因此,假设测试文件是目录中唯一以te--<代码>var=te*;echo$var返回
test
var=te*;mv$var$var.txt
返回
te*.txt
。那么我在这里使用什么策略呢。我也可以用图形文件管理器来实现这一点,但我以前也这样做过,而且觉得很无聊。

下面是一个使用
find
命令的示例

#!/bin/bash
if [[ $1 = "" ]] ; then
  echo "Please run the command specifying the filename you are searching for..."
  exit
fi
for i in $(find . -type f -name "$1" | tr -d './') ; do
  echo ${i}
  mv ${i} 01-${i}
done
然后你会跑

./scriptName "*someSongN*"

以批处理的方式进行。创建一个包含fromName到name列的映射文件,运行用于重命名的脚本

while read a b; do mv "$a" "$b"; done < filemap

并手动编辑filemap文件以添加所需的前缀。

当您只想移动一个文件时,可以创建(内联)函数,如

$ mvd() { mv $1 $2$1; }
像这样使用它

$ mvd test.mp3 01-
这将把文件
test.mp3
移动到
01 test.mp3


通过使用
find
,您可以对多个文件执行此操作,但这将导致所有文件仅以一个前缀开头(
find.-type f-name${pattern}-exec mvd{}${prefix}

另一个选项是使用
find-键入f-name${pattern}
并使用
for
对其进行迭代。然后,您可以实现一个计数器:

$ i=0; for file in $(find . -type f -name ${pattern}); do mv $file $i-$file; let i+=1; done
问候
Fabian

您是否尝试过使用
find
命令?您可以使用通配符运行
find
,然后返回文件名,您可以将其设置为一个变量。这些曲目是否包含在其中?@dawg,看起来是这样的,但无论出于何种原因,我尝试过的音乐播放器只按字母顺序播放这些文件,即使在显示曲目编号时也是如此。无论如何,我喜欢一点文件名元数据。您可以使用
Perl
Python
读取ID3标记,并使用ID3标记还原文件名(以及艺术家/专辑类型组织的目录)——假设它是准确的;mv$var$var.txt,可能是<代码>var=te*;var=$(echo${var});mv$var$var.txt这将重置您的var变量为echo显示的内容。您可以将
01
转换为循环中的另一个变量,这样您就可以拥有01 filename 02 filename 03 filename等。因此通常
find
输出当前目录,如
/thisisafile
,那么,有没有一种内置的方法来排除这种情况呢。我可以将
cut-c3-
添加到管道中,但如果有机会,我会投票。这篇文章很有帮助,只是发现@karafka的答案稍微有效一些。@cfye14我修改了代码,将
tr-d./.
包含在for循环中。这将移除“/”@cfye14还不确定是否有内置管道,但我会仔细考虑,看看是否可以移除管道。在哪里?在
ls-1
中,ah右,在
mv
操作期间。我尝试在
filemap
中更改分隔符,但没有效果。文件名中是否有空格?如果是,请在“粘贴”中设置分隔符,并将IFS设置为read.thx之前的分隔符。我不能很好地实现这个功能,但我可以在单个情况下使用该功能。另外,在find-exec中使用自定义bash函数似乎还需要做更多的工作。对于for循环,我将如何处理模式更改?
$ i=0; for file in $(find . -type f -name ${pattern}); do mv $file $i-$file; let i+=1; done