已经使用单引号和双引号时如何为 awk 添加引号?

How to add quotes for awk when single and double quotes are already used?

我想写一个别名,以便我的 squeue 命令只输出 运行ning 的模拟。对于我的 squeue 命令,我在 .bashrc 中有一个别名,如下所示

alias sq='squeue -u as1056 --format="%.18i %.36j %.8u %.2t %.10M %.10L %.6D %.6C %.12P %R"'

有了这个,我可以将 运行ning 模拟输出为

sq | awk ' == "R" {print [=11=]}'

这在命令行中按预期工作。我现在想将此命令添加为别名

alias sqrun='sq | awk " == \"R\" {print [=12=]}"'

如您所见,等号后的单引号已经用完了,因此在 awk 命令后需要双引号。但是,为了匹配第 4 列中的模式,我需要指定另一个字符串。由于已经使用了单引号和双引号,我不确定在这种情况下如何指定字符串。我尝试使用反斜杠转义双引号,但它抛出错误:

awk: cmd. line:1:  == "R" {print -bash}
awk: cmd. line:1:  ^ syntax error

那么在这种情况下我应该如何指定别名呢?

Edit1:通过在 sq 命令中匹配一个简单的 R 模式,有一种肮脏的方法。问题是它经常匹配包含单词“DRAINED”的列。所以我可以使用 sed 来删除这些行。所以像

sq | awk "/R/ {print [=14=]}" | sed "/DRAINED/d"

不会 运行 进入命令中有 3 个引号的问题。但我想避免这种方法,因为它不是通用的,如果碰巧有一个列包含 R 但不包含单词“DRAINED”,它可能会给出错误的结果。

PS:这是我关于 Whosebug 的第一个问题,所以如果您发现我提出这个问题的方式有任何错误,我将不胜感激!

您可以通过双引号单引号来链接单引号部分

alias sqrun='sq | awk '"'"'  == "R" {print [=10=]} '"'"' '

为清楚起见添加了额外的空格,但不需要。然而,这些嵌套引号可能变得非常难以阅读,并且可能不是一个好主意,除非仅用于琐碎的情况和丢弃脚本。

awk 脚本包含 $,当您将 awk 脚本周围的引号从 ' 更改为 " 时,它会使 bash 将它们视为要替换的变量.你还必须转义 $:

alias sqrun='sq | awk "$4 == \"R\" {print $0}"'

我会选择一个简单的:

alias sqrun='sq | awk '\'' == "R" {print [=10=]}'\'

或使用函数,如@DiegoTorresMilano 建议的那样(但与别名不同,找到您忘记的函数名称并不容易):

sqrun() { sq | awk ' == "R" {print [=11=]}'; }

或者如果有多个别名需要定义:

#!/bin/sh

# A little magic that will show you the way:
while IFS='' read -r cmd
do
    # define a dummy alias
    alias "unamed=$cmd"
    # then show it
    alias unamed
done <<'EOF'
squeue -u as1056 --format="%.18i %.36j %.8u %.2t %.10M %.10L %.6D %.6C %.12P %R"
sq | awk ' == "R" {print [=12=]}'
EOF

现在您可以将输出复制粘贴到您的 .bashrc 中并为您的别名命令设置一个名称

备注:

  • <<'EOF' ... EOF 引用 here-document;它会将其内容提供给命令的标准输入(while 循环)。当 引用 时,这意味着 shell 不会展开其中的任何内容。

  • read 命令从 stdin 读取一行(由 here-document 提供)。 IFS=''-r 选项用于防止 read 修改该行。