5 bash
编写一个接受两个参数的bash脚本:目录和扩展名。脚本必须打印以stdout目录中所有文件的路径(及其递归子目录),并以扩展名结尾。
到目前为止,我有:
find {directory} -type f -name ' *.extension *
Run Code Online (Sandbox Code Playgroud)
当我给它2个参数时,似乎什么也没找到。
这个脚本应该可以解决这个问题:
#!/bin/bash
find "$1" -type f -name "*.$2"
Run Code Online (Sandbox Code Playgroud)
运行脚本的示例:
/bin/bash script.sh /srv/directory css
/bin/bash script.sh '/srv/directory with space' css
Run Code Online (Sandbox Code Playgroud)
在这个答案中,我只是对 Viktor 的代码进行了一些解释。
这个解释可能对正在学习的人有所帮助 bash。在我发布“空间问题”部分之后以及在我完成撰写和保存此解释之前,维克多更新了他的答案。这就是我所希望的。
它非常简洁,并且有很好的解释。原来的代码是:
#!/bin/bash
#@filename: script.sh
find $1 -type f -name "*.$2"
Run Code Online (Sandbox Code Playgroud)
听起来这个问题来自某种作业,我想这个原始代码可能会满足作业的期望。它可能也适用于大多数您将编写的程序,如果问题不是来自作业,这一点尤其重要。
我经常在 Windows 或 Cygwin 上开发,所以我遇到了带有空格的路径和文件名。如果我在 Cygwin 上使用 @Viktor 的代码(请注意,当我在 linux 上使用 Viktor 的代码时会发生相同的行为)
$ pwd
/home/me
#Write the program
$ vim script.sh
#view the program
$ cat script.sh
#!/bin/bash
find $1 -type f -name "*.$2"
#Create a path with spaces in one of the directory names
#Name it after Viktor, for the great answer
CORP+dblack@CAP-D-ENG-INT3 ~
$ mkdir -p viktor/dir\ with\ spaces/directory
#put some css files in that directory
$ touch viktor/dir\ with\ spaces/directory/a.css
$ touch viktor/dir\ with\ spaces/directory/b.css
$ touch viktor/dir\ with\ spaces/directory/c.css
# run Viktor's code, using the well-written instructions
$ /bin/bash ./script.sh 'victor/dir with spaces/directory' css
find: ‘viktor/dir’: No such file or directory
find: ‘spaces/directory’: No such file or directory
Run Code Online (Sandbox Code Playgroud)
请注意,我使用了./script.sh而不是普通的script.sh,因为我没有设置script.sh为可执行文件。如果我第一次运行,我可以像 Viktor 显示的那样运行它
$ chmod +x script.sh
Run Code Online (Sandbox Code Playgroud)
问题来自bashshell 和find命令处理空间的方式。第一个参数简单地给出为$1,空格不会被特殊对待。这可能不是描述事物的最佳方式。或许更好的解释这个概念的方法是展示bash将分配以下内容。
$0='script.sh'
$1='viktor/dir with spaces/directory'
$2='css'
Run Code Online (Sandbox Code Playgroud)
即使我们告诉bash我们的目录有空格,这也会发生
$ /bin/bash script.sh viktor/dir\ with\ spaces/directory css
find: ‘viktor/dir’: No such file or directory
find: ‘spaces/directory’: No such file or directory
Run Code Online (Sandbox Code Playgroud)
这可以通过添加行echo "\$0 is $0"、echo "\$1 is $1"、echo "\$2 is $2"、 和其他具有$(insert_number_here_but_no_parentheses)查看,如果您愿意的话。
那么,我们如何解决这个问题呢?让我们看看手册页find
$ man find
# (press 'q' to get out of the display of the man page)
Run Code Online (Sandbox Code Playgroud)
好吧,那有点吓人。
让我们将原始概要行缩减为
find [starting-point...] [expression]
Run Code Online (Sandbox Code Playgroud)
DESCRIPTON 在其“起点”解释中的意思是[starting-point...]您将从中开始搜索的一个(或多个)目录。现在,只是从表面上看,“表达式”是限制搜索的东西——在您的情况下,您只查找文件,然后通过指定它们具有某个文件扩展名来进一步过滤结果。
让我们回到find $1 -type f -name "*.$2"命令。这里要知道的要点是,此处显示的命令将扩展为
find viktor/dir with spaces/directory -type f -name "*.css"
Run Code Online (Sandbox Code Playgroud)
“空间问题”是它会被findshell解释如下
find victor/dir with spaces/directory -type f -name "*.css"
| \ | \ `--------------------'
| \ | \ /
| | | \ Another '[expression]' (2)
| | | -- Another '[starting-point]'
| | -- '[expression]' (1)
| -- '[starting-point]' (supposedly a directory)
-- Command name
Run Code Online (Sandbox Code Playgroud)
请注意,我们的'[expression]' (1)和'[expression]' (2)不要考虑发生的情况,因为两条'[starting-place]'路径都失败了。
Viktor 代码中现在显示的内容
#!/bin/bash
#@filename viktor_script.sh
find "$1" -type f -name "*.$2"
Run Code Online (Sandbox Code Playgroud)
造成
find "viktor/dir with spaces/directory" -type f -name "*.css"
`--' `--------------------------------' `-------------------'
| | /
| | valid '[expression]' to define
| | a "filter" for files outputted
| |
| -- '[starting-point]' (a real directory)
| bash knows to include the spaces because
-- command name of the quotation marks
Run Code Online (Sandbox Code Playgroud)
让我们运行它,首先确保它是可执行的
$ chmod +x viktor_script.sh
$ /bin/bash ./viktor_script.sh css
$ /bin/bash viktor_script.sh 'viktor/dir with spaces/directory' css
viktor/dir with spaces/directory/a.css
viktor/dir with spaces/directory/b.css
viktor/dir with spaces/directory/c.css
Run Code Online (Sandbox Code Playgroud)
\xe2\x80\x99t 看起来不像你在这里使用参数。
\n\n您应该将扩展名和目录替换为 $1 和 $2 以使用参数 1 和 2。
\n\n另外,看起来您忘记关闭该引号...并且目录周围的大括号看起来错误...我认为您需要在大括号周围加上引号。
\n\n(不幸的是,目前无法测试结果,抱歉)。
\n| 归档时间: |
|
| 查看次数: |
1900 次 |
| 最近记录: |