我有一个目录,其中包含一个扩展名(在本例中为 .txt)的文件,我想自动将其转换为另一个扩展名(.md)。
是否有一个简单的终端单行程序可以用来将此目录中的所有文件转换为不同的文件扩展名?
还是我需要用正则表达式编写脚本?
我有一个目录,其中包含一个扩展名(在本例中为 .txt)的文件,我想自动将其转换为另一个扩展名(.md)。
是否有一个简单的终端单行程序可以用来将此目录中的所有文件转换为不同的文件扩展名?
还是我需要用正则表达式编写脚本?
你可以使用这样的东西:
for old in *.txt; do mv $old `basename $old .txt`.md; done
先复制一份吧!
或者,您可以安装ren
(重命名)实用程序
brew install ren
ren '*.txt' '#1.md'
如果要重命名文件名中带有前缀或后缀的文件
ren 'prefix_*.txt' 'prefix_#1.md'
不需要终端...只需突出显示要重命名的所有文件。右键单击并选择“重命名##项目”,然后在“查找:”框中键入“.txt”,在“替换为:”框中键入“.md”。
执行此操作的首选 Unix 方式(是的,OS X 基于 Unix)是:
ls | sed 's/^\(.*\)\.txt$/mv "\1.txt" "\1.md"/' | sh
为什么通过设计循环使用for
ifls
循环遍历整个文件名列表?你有管道,使用它们。您不仅可以使用命令创建/修改输出,还可以使用命令(对,即由命令创建的命令,这是 Unix 的发明者之一 Brian Kernighan 在 Unix 上最喜欢的),所以让我们来看看和ls
通过sed
移除管道产生sh
:
$ ls | sed 's/^\(.*\)\.txt$/mv "\1.txt" "\1.md"/'
mv "firstfile.txt" "firstfile.md"
mv "second file.txt" "second file.md"
$
如您所见,它不仅是一个单行脚本,而且是一个完整的脚本,它还通过创建另一个脚本作为输出来工作。因此,让我们将单行脚本生成的脚本提供给OS X的脚本解释器。当然,它甚至适用于其中包含空格的文件名sh
。
顺便说一句:每次您在终端中键入内容时,您都会创建一个脚本,即使它只是一个带有诸如ls
或之类的单词的单个命令date
。在 Unix shell 中运行的所有内容始终是一个脚本/程序,它只是一些基于 ASCII 的流(在这种情况下,指令流与数据流相对)。
要查看由 执行的实际命令sh
,只需在 之后添加一个-x
选项sh
,它会在 shell 中打开调试输出,因此您将看到每个mv
命令都使用sed
编辑器脚本传递的实际参数执行(是的,脚本中的另一个脚本: -))。
但是,如果您喜欢复杂性,您甚至可以使用awk
,如果您喜欢安装其他程序来完成基本工作,那么ren
. 我认识甚至愿意perl
为这个简单的日常任务编写一个 50 行左右的脚本的人。
也许在finder中重命名文件更容易,但如果远程连接到Mac(例如通过ssh
),则根本无法使用finder。这就是为什么 cmd 行仍然非常有用的原因。
根据上面选择的最准确的答案,这里有一个 bash 可重用函数:
function change_all_extensions() {
for old in *."$1"; do mv $old `basename $old ."$1"`."$2"; done
}
用法:
$ change_all_extensions txt md
(我无法弄清楚如何在对该答案的评论中获得干净的代码格式。)
无需为它编写脚本只需点击此命令
find ./ -name "*.txt" | xargs -I '{}' basename '{}' | sed 's/\.txt//' | xargs -I '{}' mv '{}.txt' '{}.md'
我有一个类似的问题,文件.gifx.gif
在最后命名,这在 OS X 中可以删除最后一个.gif
:
for old in *.gifx.gif; do
mv $(echo "$old") $(echo "$old" | sed 's/x.gif//');
done
cd $YOUR_DIR
ls *.txt > abc
mkdir target // say i want to move it to another directory target in this case
while read line
do
file=$(echo $line |awk -F. '{ print $1 }')
cp $line target/$file.md // depends if u want to move(mv) or copy(cp)
done < abc
list= ls
for file in $list do newf= echo $file|cut -f1 -d'.'
echo "The newf is $newf" mv $file $newf.jpg done