【问题标题】:looping object as inputs in BASH, SHELL script循环对象作为 BASH、SHELL 脚本中的输入
【发布时间】:2014-08-25 17:00:50
【问题描述】:

具有相同名称grid_200001.grb2.nc 的多个文件只有一个组件更改,即月份grid_200010.grb2.nc。我想同时使用它们作为输入文件

我希望实现的一个例子是

fname="grid_"
year="2010"
month="01 02 03 04 05 06 07 08 09 10"
ext="grb2"
end="nc"

for((y=$year;y<=$year;y++));
do
    for m in $month
    do

    ifile=$fname$y$m.$ext.$end

    >>merge $ifile $ifile ... ofile 

我想要的命令示例是

 >> merge grid_200001.grb2.nc grid_200002.grb2.nc ....grid_200012.grb2.nc ofile

我希望我可以同时作为输入文件输入的所有文件

【问题讨论】:

  • 如果你能提供更多关于你希望如何完成的细节会更好,因为我从你的解释中看到了许多可能的意图。最好不要猜测。一个伪代码也许就可以了。
  • @konsolebox 感谢您的建议,我重新编写了一个示例,希望现在更清楚我想要实现的目标
  • ofile 将在每个循环中被覆盖。这是故意的吗?另外,请正确缩进您的合并命令,以便我们知道您要运行哪个循环体。为什么cat 也不适用? cat ifile1 ifile2 &gt; ofile
  • @konsolebox 我正在使用一个特定的工具箱来合并我拥有的文件类型,不幸的是 cat 不是我可以使用的东西。目标是使用我上一步中的所有文件作为同时输入并产生一个最终输出(ofile)
  • 我明白了。仍然令人困惑的是如何获得合并源以及要合并它们的位置。你能否修改你的循环体以使其完整(以done 结尾)和-indent- 它很好,所以我们会知道更多你打算如何合并它?正如您看到的 ifile 分配和您的 merge 命令与内部 for 循环对齐。

标签: bash shell loops sh


【解决方案1】:
fname="grid_"
years=({2000..2010})
months=(01 02 03 04 05 06 07 08 09 10)  ## ({01..10}) should be the same
ext="grb2"
end="nc"

shopt -s extglob
IFS='|' eval 'pattern="${fname}@(${years[*]})@(${months[*]}).${ext}.${end}"'
echo "pattern = ${pattern}"  ## for curiosity.
files=($pattern)  ## pathname expansion is sorted in Bash.

merge "${files[@]}" ofile

【讨论】:

  • 为了理解你使用模式作为所有文件的“阅读器”的过程,你使用通配符(*)来确保所有具有 fname 的文件都作为输入包含(正确吗??)然后在合并命令中我可以命名模式=文件并将它们全部用作同时输入(?)@是什么意思?
  • 是的,它是一个通配符模式,但是一个extended form"{files[@]}" 正确扩展为多个参数。你可以通过echo merge "${files[@]}" ofile 来了解你的命令是如何进行的。
【解决方案2】:

我不确定我是否完全理解这个问题(感谢您的 cmets 编辑)

filenames=""

for year in $(seq 2000 2010)
do 
    for month in $(seq -w 0 10)
    do 
        filename="grid_"$year$month".grb2.nc"
        filenames=$filenames" "$filename
    done
done
your_command $filenames

这可能是您需要的? cat 和通配符很好,但它会保持相同的顺序吗?

再次编辑: 但是,如果您只需要按升序排列通配符,则your_command grid_20[01][0-9][01][0-9].grb2.nc 的选择要简单得多(通配符总是这样吗?)

【讨论】:

  • 正如我所提到的,我有之前在代码中生成的文件。文件的名称通常很长,但我给出了我想要创建的代码示例以使其更易于阅读。不幸的是,如果我此时使用通配符,我会危及进程,因为通常我有 20-50 个名称相似的文件。
  • @Emillien 您可以使用seq -w 0 10 填充零
  • 感谢 -w 提示,它好多了! @George我仍然没有得到你想要的东西,你需要把所有这些名字放在一个字符串中,并按照这个顺序,这样你就可以将命令应用于所有这些名字吗?在您的问题中,merge $ifile ... ofile 不清楚
  • @Emilien 是的,我想取所有文件的名称,然后按升序排列,然后我使用的命令将处理其余部分。
【解决方案3】:

你可以试试这个:

cat grid_2010[01][0-9].grb2.nc >> ofile

【讨论】:

  • 我不想使用 cat,我使用的工具箱需要将所有相同的文件用作同时输入。整个事情是更大脚本的一部分,这是一个步骤,但我对如何同时使用多个文件作为输入感到困惑
  • @George 我不知道你的目的是什么,但在你的脚本中你没有使用“.grb2”。考虑到这一点,你注意到了吗?
  • 感谢您的通知,我没有注意到,我现在会更正它。我试图在简单的例子中给出代码,而不是使用我的输入
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-08-16
  • 2019-10-03
  • 2017-04-29
  • 1970-01-01
  • 2019-09-16
  • 2012-06-28
相关资源
最近更新 更多