【问题标题】:how does a while read loop work in bash?while 读取循环如何在 bash 中工作?
【发布时间】:2016-10-27 17:14:15
【问题描述】:

This is a crawler from GitHub 我要自己实现,但由于是新手,所以无法阅读 bash。这可以在答案中解释吗

#!/bin/bash

# Create an array files that contains list of filenames
files=($(< url.txt))
cities=($(< city.txt))
url="http://www.grotal.com/"
citycodes=($(<citycode.txt))

# Read through the url.txt file and execute wget command for every filename
while IFS='=| ' read -r param uri; do
    for file in "${files[@]}"; do
        for city in "${cities[@]}"; do
            mkdir "${city}"
            mkdir "${city}/${file}"
            wget -O "${city}/${file}/${file}${citycodes[@]}" "${uri}${url}${city}/${file}-${citycodes[@]}/"
        done
    done
done < url.txt

特别是这些(即使你选择投反对票...)

while IFS='=| ' read -r param uri;

然后是这个:

done < url.txt

【问题讨论】:

  • 请参阅BashFAQ #1,其中详细描述了while read 循环。
  • 另外,filescities 数组的填充方式非常错误。 mapfile -treadarray -tread -r -a 会好得多。
  • 无论如何——如果您问“while 读取循环如何在 bash 中工作?”,那将是一个更好的问题。包括循环体内容、预先设置内容等。将问题的范围扩大到此处的话题性……值得怀疑的程度。请参阅stackoverflow.com/help/how-to-ask,尤其是关于什么是好的标题的部分(需要针对个别问题!)
  • ...关于“请向我解释这段代码”的问题,以及为什么将它们关闭过于宽泛是公认的做法:meta.stackoverflow.com/questions/278797/…meta.stackoverflow.com/questions/253894/…

标签: bash web-crawler


【解决方案1】:

让我们把它分解成几部分:

  • read,除非给定一个非默认的 -d 参数来指定一个终止符来代替换行符,否则从标准输入读取一行(即,读取到下一个换行符);在 IFS 字符上拆分该行,并将每个字段写入不同的变量。如果它在到达换行符之前停止读取更多数据,那么它会发出非零退出状态,即使它成功填充了给定的变量。 (-r 参数防止 read 将反斜杠视为连续字符而不是文字;除非您有特定理由在手头的上下文中提供连续字符,否则您应该养成将 -r 传递给 @987654327 的习惯@ 默认)。
  • &lt; url.txturl.txt 上的读取句柄重定向到附加它的命令(包括复合命令,例如 while 循环)的标准输入中。
  • while 循环运行它给出的条件命令,检查该条件是否报告成功或失败,然后继续运行主体并在成功时重新启动,或在失败时退出。

因此,如果您有IFS='=| ' read -r param uri,它将从标准输入读取一行;将直到第一个=| 或空格的所有内容分配给名为param 的变量,并将剩下的分配给变量uri

如果你把它放在while 循环的条件部分,那么循环将一直运行直到read 失败——就像没有更多内容时一样(直到并包括换行符)可供阅读。

有关该成语及其用途的更深入讨论,请参阅BashFAQ #1


一些旁白:

  • 使用mkdir -p -- "${city}/${file}" 将使您只有一个mkdir 命令来创建两个目录(如果它们已经存在,则避免生成错误消息)。
  • 使用readarray -t files &lt; url.txt 是一种将url.txt 的内容读入名为files 的数组的更可靠的方法,尽管它需要bash 4.0 或更高版本。对于旧版本的 shell,请考虑 IFS=$'\n' read -r -d '' -a files &lt;url.txt || (( ${#files[@]} ))。如果您的输入文件中包含通配符、空格或其他意外内容,这些将比原始惯用语表现得更好。

【讨论】:

    猜你喜欢
    • 2020-10-21
    • 2022-01-23
    • 1970-01-01
    • 2019-05-06
    • 1970-01-01
    • 2018-09-05
    • 1970-01-01
    • 2012-01-24
    • 2013-10-12
    相关资源
    最近更新 更多