【问题标题】:Combining variable concatenation and for loops in bash在 bash 中结合变量连接和 for 循环
【发布时间】:2020-04-21 09:33:10
【问题描述】:

我在 R 中有这个函数,我用它来生成日期列表:

#! usr/bin/env Rscript

date_seq = function(){
        args = commandArgs(trailingOnly = TRUE)
    library(lubridate)
    days = seq(ymd(args[1]),ymd(args[2]),1)
    days =format(days, "%Y%m%d")
    return(days)

}   
date_seq()

我在 bash 脚本中调用此函数来创建日期向量:

Rscript date_seq.R 20160730 20160801 > dates

我在 bash 脚本中定义了其他几个字符串变量:

home_url="https://pando-rgw01.chpc.utah.edu/hrrr/sfc/"
file_name="/hrrr.t{00-23}z.wrfsfcf00.grib2"

最终目标是创建一个下载链接向量,其中包含三个变量home_urldatefile_name,如下所示:

"https://pando-rgw01.chpc.utah.edu/hrrr/sfc/20160730/hrrr.t{00-23}z.wrfsfcf00.grib2"
"https://pando-rgw01.chpc.utah.edu/hrrr/sfc/20160731/hrrr.t{00-23}z.wrfsfcf00.grib2"
"https://pando-rgw01.chpc.utah.edu/hrrr/sfc/20160801/hrrr.t{00-23}z.wrfsfcf00.grib2"

我在 bash 脚本中尝试了几行:

  • for date in $dates; do download_url=$home_url$date$hrrr_file; cat $download_url; done
  • for date in $dates; do download_url="${home_url}${date}${hrrr_file}"; cat $download_url; done
  • for date in $dates; do download_url="$home_url"; download_url+="$date"; download_url+="$hrrr_file"; cat $download_url; done

这些都不会产生我期望的输出。我不确定download_url 变量是否没有被生成,或者正在生成并存储在某个地方,我无法重现它。谁能帮我理解一下?

编辑
尝试以下建议的结果:

  • @triplee 建议使用
    sed "s#.*#$home_url&$hrrr_file#" "dates"
    
    while read -r date; do; printf '%s%s%s\n' "$home_url" "$date" "$hrrr_file"; done <dates
    
    这两个都会产生这个输出:
    https://pando-rgw01.chpc.utah.edu/hrrr/sfc/[1] "20160730" "20160731" "20160801"/hrrr.t{00-23}z.wrfsfcf00.grib2
    
  • @xdhmoore 建议使用
    for date in $(cat dates); do; echo ${home_url}${date}${hrrr_file}"; done
    
    产生这个输出:
    https://pando-rgw01.chpc.utah.edu/hrrr/sfc/[1]/hrrr.t{00-23}z.wrfsfcf00.grib2
    https://pando-rgw01.chpc.utah.edu/hrrr/sfc/"20160730"/hrrr.t{00-23}z.wrfsfcf00.grib2
    https://pando-rgw01.chpc.utah.edu/hrrr/sfc/"20160731"/hrrr.t{00-23}z.wrfsfcf00.grib2
    https://pando-rgw01.chpc.utah.edu/hrrr/sfc/"20160801"/hrrr.t{00-23}z.wrfsfcf00.grib2`
    

虽然@xdhmoore 的解决方案更接近,但两者都不是我期望的输出。但是我在@xdhmoore 的解决方案中看到了另一个问题:输出中日期周围的引号。 cat dates 的输出看起来像这样:"20160730" "20160731" "20160801",所以我认为我必须重新编写函数或在 bash 脚本中调用它的方式。

我会不断更新问题以反映所有建议的输出,因为这样做比尝试回答每条评论更简单。一如既往,非常感谢!

【问题讨论】:

  • 我想你想echo $download_url 而不是cat 它。或者可能是curl它。
  • @xdhmoore 最终,是的,我们的想法是使用curl 下载这些链接所代表的文件,但在我到达那里之前,我想确保脚本正在生成正确的下载链接,这就是我想查看链接的原因。此外,echo $download_urlecho "$download_url" 在屏幕上显示 download_url 变量方面没有任何作用。
  • 我认为您还需要 cat 日期文件:for date in $(cat dates)
  • 我对 Rscript 一无所知,但看起来日期文件包含您的 date_seq() 返回对象的默认序列化版本。与其返回并将其序列化并打印出来,也许有一种方法可以在date_seq() 中显式打印出这些值?这应该摆脱引号和 [1] 希望。
  • 实际上,我认为[1] 可能来自date_seq() 中的一个错误,但就像我说的,我不知道任何Rscript,所以我不确定。

标签: bash concatenation rscript


【解决方案1】:

for 语句循环遍历您作为参数提供给它的标记,而不是文件的内容。

你似乎在寻找

sed "s#.*#$home_url&$hrrr_file#" "dates"

标记&amp; 召回与sed 替换中的正则表达式匹配的文本。

同样的事情可以大大地用一个shell循环更慢地完成;

while read -r date; do
    printf '%s%s%s\n' "$home_url" "$date" "$hrrr_file"
done <dates

这说明了如何在不使用外部实用程序的情况下(缓慢地)迭代文件中的行。

这些中的任何一个都可以通过管道传输到xargs curl(或者可能是xargs -n 1 curl);或者你可以重构 while 循环;

while read -r date; do
    curl "$home_url$date$hrrr_file"
done <dates

如 cmets 中所述,cat 是用于复制文件的命令,而不是回显文本;对于后者,使用echo 或(对于任何重要的格式)printf

更新:以上假设您的 R 输出每行生成一个日期。要将文件拆分为行并删除值周围的引号,您可以使用sed 's/"\([^"]\)" */\1\n/g' "dates" 进行预处理(前提是您的sed 方言支持\n 作为换行符的转义);或者也许做

sed "s#\"\([^\"]*\)\" *#$home_url\\1$frrr_file\\
#g" "dates"

再次对sed 方言之间的差异有所保留。在最坏的情况下,也许改用 Perl,这实际上可以缓解反斜杠的问题,但在其他地方需要新的反斜杠:

perl -pe "s#\"(\d+)\" *#$home_url\$1$frrr_file\n#g" "dates"

但可能更好的解决方案是更改您的 R 脚本,使其不会产生古怪的输出。或者一开始就不要使用 R。参见例如https://stackoverflow.com/a/3494814/874188 了解如何从 Perl 获取日期。或者如果你有 GNU date,试试

#!/bin/bash
start=$(date -d "$1" +%s)
end=$(date -d "$2" +%s)
for ((i=start; i<=end; i+=60*60*24)); do
    date -d "@$i" +%Y%m%d
done

(如果您使用的是 Mac 或类似设备,date 程序不会接受日期作为-d 的参数,您将不得不使用稍微不同的语法。这并不难,但这个答案有已经有太多猜测了。)

【讨论】:

  • 对删除的评论感到抱歉,请参阅上面的编辑。
猜你喜欢
  • 2012-10-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-02-13
  • 2016-07-13
  • 2019-05-31
  • 1970-01-01
  • 2011-06-02
相关资源
最近更新 更多