我们使用一个脚本将 bash 命令打印到文件中,然后在 HPC 系统上运行。它应该运行一个包含由空格分隔的地理坐标的大型文本文件,并从该文件中提取特定区域(例如,提取 x 坐标介于 xmin 和 xmax 之间且 y 坐标介于 ymin 和 ymax 之间的所有行)。
理想情况下,我希望像这样使用 awk 来实现这一点(因为我现在没有电脑,所以只能凭记忆来):
awk -v xmin=-13000 -v xmax=13000 -v ymin=-500 -v ymax=500 -F ' ' {if ($1 > xmin && $1 < xmin && $2 > ymin && $2 < ymin) print $1 $2} $infile > $outfile
这可能执行得很好。但是,正如标题所示,我们间接为 25 个区域保存了此行,每个区域都有自己的 xmin、xmax 等。之后还有更多操作(使用 GMT 调用等)。这里有一个小片段:
xmin=-13000
xmax=13000
ymin=-500
ymax=500
infile=./full_file.txt
outfile=./filtered_file.yxy
srcfile=./region_1.txt
echo """awk -v xmin=$xmin -v xmax=$xmax -v ymin=$ymin -v ymax=$ymax -F ' ' {if ($1 > $xmin && $1 < $xmin && $2 > $ymin && $2 < $ymin) print $1 $2} $infile > $outfile""" >> $srcfile
显然,由于变量扩展,这会在运行时引发错误。我尝试过转义 awk 列标识符,但无济于事,或者没有正确理解模式。有人能告诉我一个允许我们保留间接方法的解决方案吗?
IIUC,你必须像这样逃避每一个美元符号:
或者暂时关闭双引号并将美元符号放在单引号中:
或者使用 Bash 特定的
%q
printf 说明符:'
而且我认为如果您不想让 shell 扩展变量的话,最好将 awk 代码括起来。创建单独的临时脚本似乎没有必要。只需循环遍历参数即可。
这
____
只是更传统的EOF
heredoc 分隔符的一个巧妙替代品。here document 中的每一行都应该是 中变量的一组值read
。如果您确实想要将每个片段打印到单独的文件中(例如,可能将每个片段提交到不同的集群节点上运行),也许可以学习使用
printf
而不是echo
。(尽管将命令打印到
.txt
文件仍然很奇怪)。不管怎样,您尝试的三重引号没有任何用处。 Python (例如) 有这种语法,但在 shell 中,
"""
它只是将其解析为一对引号内的空字符串,""
后跟一个打开的双引号"
。类似地,
printf
上面的例子演示了一种在单引号字符串中生成文字单引号的方法。'foo'"'"'bar'
是(单引号)foo
旁边是双引号'
旁边是单引号bar
,当将它们粘贴在一起时会产生foo'bar
。我还稍微重构了你的 Awk 脚本,使其更加符合惯用语,并修复了缺失的引用
如果要执行此操作,请考虑以下几点,以确保在创建 awk 脚本时所有变量都用双引号引起来,并且 awk 脚本使用它们的值时都用单引号引起来:
也就是说,每个 here-doc 分隔符的开头都有 4 个空格
!
,并且 here-doc 中每行的开头都有一个制表符,后面跟着空格。