如果您想建立您的极客信誉,请加入我们的shell脚本系列的第二部分。我们对上周的脚本进行了一些修改和改进,并为新手提供了一个循环指南。
在shell脚本指南的第一部分中,我们编写了一个脚本,在文件名末尾添加日期后,将文件复制到备份目录。
SamuelDionneRiel在评论中指出,有一种更好的方法来处理变量引用。
Arguments are space-separated in the bash shell, it will tokenize when there is a space in the resulted expanded command. In your script, cp $1 $2.$date_formatted will work as intended as long as the expanded variables do not have spaces in them. If you call your script this way: datecp "my old name" "my new name" the expansion will result in this command: cp my new name my old name.the_date which actually has 6 arguments.
To properly address this issue, the last line of the script should be: cp "$1" "$2.$date_formatted"
如您所见,将我们的脚本行从:
cp -iv $1 $2.$date_formatted
收件人:
cp -iv “$1” “$2”.$date_formatted
在名称中包含空格的文件上使用脚本时,将解决此问题。Samuel还指出,当从这个站点(或一般的互联网)复制和粘贴代码时,一定要用适当的破折号和引号替换那些经常替换它们的“排版更好”的破折号和引号。我们还将做更多的工作来确保我们的代码更易于复制/粘贴。;-)
另一位评论者Myles Braithwaite决定扩展我们的脚本,以便日期出现在文件扩展之前。所以
tastyfile.mp3.07_14_11-12.34.56
我们会得到:
tastyfile.07_14_11-12.34.56.mp3
最终对大多数用户来说更方便一点。他的代码可以在他的GitHub页面上找到。让我们看看他用什么来分解文件名。
date_formatted=$(date +%Y-%m-%d_%H.%M%S) file_extension=$(echo “$1″|awk -F . ‘{print $NF}’) file_name=$(basename $1 .$file_extension)
cp -iv $1 $file_name-$date_formatted.$file_extension
我对格式做了一些修改,但是可以看到Myles在第1行声明了他的日期函数。但是,在第2行中,他使用“echo”命令和脚本的第一个参数来输出文件名。他使用pipe命令获取输出并将其用作下一部分的输入。完成管道后,Myles调用“awk”命令,这是一个强大的模式扫描程序。使用-F标志,他告诉命令下一个字符(空格后)将定义“字段分隔符”。在这种情况下,这是一个时期。
现在,awk看到一个名为美味文件.mp3由两个字段组成:“tastyfile”和“mp3”。最后,他使用
‘{print $NF}’
显示最后一个字段。如果文件有多个句点,因此awk会看到多个字段,它将只显示最后一个字段,即文件扩展名。
在第3行中,他为文件名创建了一个新变量,并使用“basename”命令引用$1中除文件扩展名以外的所有内容。这是通过使用basename并将$1作为参数,然后添加一个空格和文件扩展名来实现的。由于引用第2行的变量,文件扩展名将自动添加。这样做的目的是
tastyfile.mp3
把它变成
tastyfile
在最后一行中,Myles整理了一个命令,该命令将按顺序输出所有内容。请注意,没有对脚本的第二个参数$2的引用。这个特定的脚本将把所说的文件复制到您当前的目录中。干得好塞缪尔和迈尔斯!
我们在基础文章中还提到,默认情况下,脚本不允许作为命令引用。也就是说,您必须指向脚本的路径才能运行它:
./script
~/bin/script
但是,通过将脚本放在~/bin/中,您只需从任何地方键入它们的名称即可运行它们。
评论者们花了一些时间来讨论这有多合适,因为没有一个现代Linux发行版默认创建这个目录。此外,默认情况下也没有人将其添加到$PATH变量中,这是脚本像命令一样运行所必需的。我有点困惑,因为在检查了$PATH变量之后,注释者是对的,但是调用脚本仍然对我有效。我发现了原因:许多现代Linux发行版在用户的主目录–.profile中创建了一个特殊的文件。
此文件由bash读取(除非用户的主目录中存在.bash\u profile),在底部,有一个部分将~/bin/folder添加到$PATH变量(如果存在)。所以,这个谜团被解开了。对于本系列的其余部分,我将继续将脚本放在~/bin/目录中,因为它们是用户脚本,应该能够由用户运行。而且,似乎我们真的不需要手动处理$PATH变量来让事情正常工作。
让我们来看看极客武器库中处理重复性任务最有用的工具之一:循环。今天,我们将讨论“for”循环。
for循环的基本轮廓如下:
for VARIABLE in LIST; do command1 command2 … commandn done
变量可以是任何变量,尽管通常按约定使用小写“i”。列表是项的列表;可以指定多个项(用空格分隔)、指向外部文本文件或使用星号(*)表示当前目录中的任何文件。列出的命令按约定缩进,因此更容易看到嵌套—将循环放入循环中(这样可以在循环时循环)。
因为列表使用空格作为分隔符—也就是说,空格表示移动到列表中的下一项—所以名称中有空格的文件不是很友好。现在,让我们继续使用没有空间。让从一个简单的脚本开始,显示当前目录中的文件名。在~/bin/文件夹中创建一个名为“loopscript”的新脚本。如果您不记得该怎么做(包括将其标记为可执行文件和添加hash-bang hack),请参阅我们的bash脚本基础文章。
在其中,输入以下代码:
for i in item1 item2 item3 item4 item5 item6; do echo “$i” done
当您运行脚本时,应该将这些列表项作为输出。
很简单吧?让我们看看如果我们稍微改变一下会发生什么。更改脚本,使其显示以下内容:
for i in *; do echo “$i” done
当您在文件夹中运行此脚本时,您应该得到它作为输出包含的文件列表。
现在,让我们将echo命令更改为更有用的东西,比如zip命令。也就是说,我们将把文件添加到归档中。我们来讨论一下吧!
for i in $@; do zip archive “$i” done
有新东西!“$@”是“$1$2$3…$n”的快捷方式。换句话说,它是您指定的所有参数的完整列表。现在,看看当我用几个输入文件运行脚本时会发生什么。
你可以看到哪些文件在我的文件夹中。我用六个参数运行了这个命令,每个文件都被添加到一个名为存档.zip”. 很简单,对吧?
因为循环是非常美妙的。现在可以对文件列表执行批处理函数。例如,可以将脚本的所有参数复制到压缩的存档中,将原始文件移动到其他文件夹,并自动将压缩文件安全复制到远程计算机。如果你用SSH设置密钥文件,你甚至不需要输入密码,你甚至可以告诉脚本在上传zip文件后删除它!
使用for循环可以很容易地对目录中的所有文件执行一系列操作。您可以将各种各样的命令堆叠在一起,并且可以非常轻松地使用参数来创建即时列表,这只是冰山一角。
你有什么建议吗?你做了一个有用的脚本,使用循环?想分享你对这个系列的想法吗?留下一些评论和帮助其他脚本新手了!
...有时会添加恼人的格式标记(如标记)。使用简单的shell脚本,您可以通过几个简单的命令自动清除那些垃圾HTML格式。 ...
...l还可以执行存储在文件中的命令。这种执行模式称为shell脚本,本文将介绍shell脚本的基础知识。 ...
... 此外,还有一个Bash脚本部分,它解释了可以在命令行中进行的基本编程。这包括变量、if语句、循环和函数。如果你不熟悉这些,不用担心——它们相当简单! ...
...如果您喜欢命令行而不是图形窗口,或者如果您喜欢使用脚本自动化任务,那么您将喜欢PowerShell提供的功能。 ...
... 注意:从我们的AppleScript语法和工作流入门指南开始。 ...
...们将一起创建一个简短的Python,不过如果您想获取完成的脚本,可以从Pastebin复制代码。 ...
...l中的VBA,请不要忘记我们也为您提供了一个极好的excelvba入门指南。 ...
Python是当今世界上最流行的编程语言之一。虽然大多数人可能把它的流行归因于它在数据科学和机器学习等领域的应用,但它也很容易学习语法,因此深受初学者的喜爱。 ...