当前位置: 首页 > 科技观察

Bash中如何使用loop

时间:2023-03-17 01:40:33 科技观察

使用loop和find命令自动对多个文件批量执行一系列操作。人们想要学习批处理命令的一个常见原因是获得批处理的强大功能。如果你想对文件批量执行一些命令,构造一个可以在这些文件上重复运行的命令是一种方法。在编程术语中,这称为执行控制,for循环是最常见的一种。for循环可以详细描述您希望计算机对您指定的每个数据对象(例如文件)执行的操作。循环的一般用途的一个简单示例是对一组文件执行分析。这个循环可能毫无用处,但它是证明自己有能力独立处理文件夹中每个文件的安全方法。首先创建一个文件夹,将一些文件(如JPEG、PNG等)复制到文件夹中,生成测试环境。您可以通过文件管理器或终端完成创建文件夹和复制文件的操作:$mkdirexample$cp~/Pictures/vacation/*.{png,jpg}example切换到刚刚创建的新文件夹,然后列出文件并确认这个测试环境是你需要的:$cdexample$ls-1cat.jpgdesign_maori.pnotago.jpgwaterfall.png在一个循环中一个一个地遍历文件的语法是:首先声明一个变量(例如,使用f表示文件),然后定义一个数据集,您希望使用该变量循环。在这种情况下,使用*通配符迭代当前文件夹中的所有文件(通配符*匹配所有文件)。然后使用分号(;)结束语句。$forfin*;根据您的个人喜好,您可以选择在此处按回车键。在语法完成之前,shell不会尝试执行循环。接下来,定义您要在每个循环中执行的操作。为简单起见,使用file命令获取有关存储在f变量中的文件的各种信息(使用$告诉shell使用此变量的值,无论变量当前存储的是什么):dofile$f;以另一个分号结束这一行,然后关闭循环:done按回车键开始shell遍历当前文件夹下的所有内容。for循环会将文件一个一个地分配给变量f并执行您的命令:$forfin*;do>file$f;>donecat.jpg:JPEG图像数据,EXIF标准2.2design_maori.png:PNG图像数据,4608x2592,8-bit/colorRGB,non-interlacedotago.jpg:JPEG图像数据,EXIF标准2.2waterfall.png:PNG图像数据,4608x2592,8-bit/colorRGB,non-interlaced你也可以这样写命令:$forfin*;做文件$f;donecat.jpg:JPEG图像数据,EXIF标准2.2design_maori.png:PNG图像数据,4608x2592,8-bit/colorRGB,non-interlacedotago.jpg:JPEG图像数据,EXIF标准2.2waterfall.png:PNG图像数据,4608x2592,8位/彩色RGB,非交错对于您的shell,多行和单行格式之间没有区别,并且将输出完全相同的结果。一个实际的例子下面是一个日常使用的循环的实际例子。假设您有一堆度假照片要发送给您的朋友。但是您的照片太大,无法通过电子邮件发送或上传到图像共享服务。因此,您想创建照片的小型Web版本,但又不想花太多时间一张一张地压缩图像大小。首先,在Linux、BSD或Mac上使用包管理器安装ImageMagick命令。例如,在Fedora和RHEL上:$sudodnfinstallImageMagick在Ubuntu和Debian上:$sudoaptinstallImageMagick在BSD上,使用端口或pkgsrc安装。在Mac上,使用Homebrew或MacPorts安装。安装ImageMagick后,您将拥有一组可用于操作图像的新命令。为您要创建的文件创建一个目标文件夹:$mkdirtmp使用以下循环会将每个图像缩小到其原始大小的33%。$forfin*;转换$f-scale33%tmp/$f;done然后就可以在tmp文件夹中看到缩小后的照片了。您可以在循环主体中使用任意数量的命令,因此如果您需要对一批文件执行复杂操作,请将命令放在for循环的do和done语句之间。例如,假设您要将所有处理过的图像复制到您网站托管的图像文件夹中,并在本地删除这些文件:$forfin*;doconvert$f-scale33%tmp/$fscp-iseth_webtmp/$fseth@example.com:~/public_htmltrashtmp/$f;done您的计算机将自动为for中处理的每个文件执行3个命令环形。这意味着如果您只处理10张图像,您还将节省输入30条命令和更多时间。限制循环循环通常不需要处理所有文件。在示例文件夹中,您可能需要处理的只是JPEG文件:$forfin*.jpg;转换$f-scale33%tmp/$f;done$ls-mtmpcat.jpg,otago.jpg或者,你想重复一个操作特定的次数而不是仅仅处理文件。for循环中变量的值由您分配给它的数据(无论类型如何)决定,因此您可以创建一个遍历数字而不仅仅是文件的循环:$fornin{0..4};做echo$n;done01234更多循环现在您已经足够了解如何创建自己的循环体了。在您非常熟悉循环之前,请尽可能多地处理您需要处理的文件的副本。使用内置的保护措施来防止损坏您自己的数据和犯下不可重现的错误,例如不小心将文件夹中的所有文件重命名为相同的名称,这可能会导致它们相互覆盖。有关for循环的更多主题,请继续阅读。并非所有的shell都是BashBashshell中内置的关键字for。许多类似的shell使用与Bash相同的关键字和语法,但有些shell,例如tcsh,使用不同的关键字,例如foreach。tcsh的语法类似于Bash,但更严格。例如在下面的例子中,不要输入foreach?在终端的第2和第3行。这只是提醒您仍处于构建循环中。$foreachf(*)foreach?文件$fforeach?endcat.jpg:JPEG图像数据,EXIF标准2.2design_maori.png:PNG图像数据,4608x2592,8-bit/colorRGB,non-interlacedotago.jpg:JPEG图像数据,EXIF标准2.2waterfall.png:PNG图像数据,4608x2592,8位/彩色RGB,非隔行扫描在tcsh中,foreach和end必须出现在一行中。所以你不能像Bash或其他类似的shell那样只用一行来创建for循环。for循环和find命令理论上,您可能使用不支持for循环的shell,或者您只是更喜欢使用其他命令的某些特性来完成与循环相同的工作。使用find命令是实现for循环功能的另一种方法。此命令提供了多种方式来定义循环中包含哪些文件的范围以及并行处理的选项。顾名思义,find命令可帮助您查询存储在硬盘驱动器上的文件。它的用法很简单:提供一个你希望它搜索的位置的路径,find会查询这个路径下的所有文件和文件夹。$find.../cat.jpg./design_maori.png./otago.jpg./waterfall.png您可以通过添加名称的特定部分来过滤搜索结果:$find。-name"*jpg"./cat.jpg./otago.jpgfind命令的好处在于,您可以使用-exec标志将它找到的每个文件放入一个循环中。例如,仅压缩示例文件夹中存储的PNG图像:$find.-name"*png"-execconvert{}-scale33%tmp/{}\;$ls-mtmpdesign_maori.png,waterfall.png在-exec短语中,方括号{}表示查找正在处理的项目(换句话说,找到的每个以PNG结尾的文件)。-exec短语必须以分号结尾,但Bash也经常使用分号。为了解决这个二义性问题,你的终结符可以使用一个反斜杠加一个分号(\;),这样find命令就可以知道这个终结符是用来标记它的使用结束的。find命令非常有用,在某些情况下甚至更好。例如,如果您在新进程中使用相同的命令查找PNG文件,您可能会收到一些错误消息:$find.-name"*png"-execconvert{}-flip-floptmp/{}\;convert:unabletoopenimage`tmp/./tmp/design_maori.png':Nosuchfileordirectory@error/blob.c/OpenBlob/2643....似乎find不只是定位当前文件夹(.)中的所有PNG文件,包括已经处理并存储在tmp中的文件。在某些情况下,您可能希望find查询当前目录及其子文件夹中的所有文件。find命令是一个强大的递归工具,尤其是在处理复杂的文件结构时(例如充满音乐家音乐专辑的文件夹),您还可以使用-maxdepth选项来限制最大深度。递归深度。仅在当前文件夹(不包括子文件夹)中查找PNG文件:$find.-maxdepth1-name"*png"将上一条命令的最大深度加1,查找并处理当前文件夹和下一级子文件夹下的文件:$find.-maxdepth2-name"*png"查找命令默认搜索每一层文件夹。循环的乐趣和好处您使用循环的次数越多,您就可以节省更多的时间和精力来处理更大的任务。尽管您只是一个用户,但通过使用循环,您可以让您的计算机完成困难的任务。您可以而且应该像使用任何其他命令一样使用循环。当您需要重复处理单个或多个文件时,请尽可能使用此命令。无论如何,这是一个需要认真对待的编程活动,因此如果您需要对某些文件完成复杂的任务,您应该花更多的时间来规划您的工作流程。如果你可以在单个文件上完成你的工作,那么将操作包装在for循环中就相对简单了,这里唯一需要的“编程”是了解变量的工作原理并做足够的规划工作,将已处理的文件与未处理的文件分开。稍加练习,您就可以从Linux用户变成知道如何使用循环的人,所以开始让计算机为您工作吧!