bash - 修改 awk 代码块内的 shell 变量

标签 bash shell variables awk

有什么方法可以修改 awk 代码块中的 shell 变量吗?

--------- [shell_awk.sh]---------------------
 #!/bin/bash

shell_variable_1=<value A>
shell_variable_2=<value B>
shell_variable_3=<value C>

awk 'function A(X)
{ return X+1 }
{ a=A('$shell_variable_1')
  b=A('$shell_variable_2')
  c=A('$shell_variable_3')
  shell_variable_1=a
  shell_variable_2=b
  shell_variable_3=c
}' FILE.TXT
--------- [shell_awk.sh]---------------------

这是一个非常简单的例子,真正的脚本加载一个文件并使用函数进行一些更改,我需要将更改前的每个值保存到一个特定的变量中,这样我就可以将前后值注册到 MySQL 中。

后值是从参数($1、$2 等)接收的。

在我已经知道如何从文件中获取它之前的值。

除了 shell_variable 由 awk 变量设置外,一切都很好。从 awk block 代码外部很容易设置,但在内部,这可能吗?

最佳答案

没有任何程序——awk、shell 或任何其他语言——可以直接修改父进程的内存。这包括变量。但是,当然,您的 awk 可以将内容写入标准输出,父 shell 可以读取该内容并自行修改自己的变量。


这是一个 awk 的例子,它写出键/值对以供 bash 读取。它并不完美——请阅读下面的注意事项。

#!/bin/bash

shell_variable_1=10
shell_variable_2=20
shell_variable_3=30

run_awk() {
        awk -v shell_variable_1="$shell_variable_1" \
            -v shell_variable_2="$shell_variable_2" \
            -v shell_variable_3="$shell_variable_3" '
        function A(X) { return X+1 }
        { a=A(shell_variable_1)
          b=A(shell_variable_2)
          c=A(shell_variable_3) }
        END {
          print "shell_variable_1=" a
          print "shell_variable_2=" b
          print "shell_variable_3=" c
        }' <<<""
}

while IFS="=" read -r key value; do
        printf -v "$key" '%s' "$value"
done < <(run_awk)

for var in shell_variable_{1,2,3}; do
  printf 'New value for %s is %s\n' "$var" "${!var}"
done

优势

  • 不使用evalawk 输出中的 $(rm -rf ~) 等内容不会被您的 shell 执行。

缺点

  • 无法处理带有换行符的可变内容。 (您可以通过使用 NUL 分隔 awk 脚本的输出并将 -d '' 添加到 read 命令来解决此问题)。<
  • 恶意 awk 脚本可以修改 PATHLD_LIBRARY_PATH 或其他安全敏感变量。 (您可以通过将变量读入关联数组而不是全局命名空间,或者通过在它们的名称上强制使用前缀来解决此问题)。
  • 上面的代码使用了几个 bash 中也可用的 ksh 扩展;但是,它不会与 POSIX sh 一起运行。因此,一定不要通过 sh scriptname 运行它(它只保证 POSIX 功能)。

关于bash - 修改 awk 代码块内的 shell 变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34866678/

相关文章:

javascript - 如何将包含另一个div的类的变量传递给JS函数并使用它来显示/隐藏相应的div?

bash - 如何让 GNU screen 识别 UTF-8 字符

linux - 如何获取与预推 git Hook 中的原始文件不同的所有文件的列表

css - gwt在css中使用静态变量

linux - 将多个记录合并为具有所有非空值的唯一记录

linux - 在 Linux 终端中输入 "cd.."而不是 "cd .."

bash - 使用 bc 或其他标准实用程序的任意数量的标准偏差

c++ - 与相应的 cpp 代码相比,为什么这个 bash 代码这么慢?

linux - 发送 ssh 命令时防止本地 shell 替换变量

linux - 使用 awk 或 bash 在 Unix 中创建包含 0 个字节的多个空文件?