【问题标题】:Line by line parsing with bash -c使用 bash -c 逐行解析
【发布时间】:2021-11-03 10:07:42
【问题描述】:

在 bash 中,我逐行解析文件并提取第一个和第二个字段,如下所示:

$ cat myfile
a1 1
a2 2
a3 3
a4

$ while read -r first second; do echo first is $first second is $second; done < myfile
first is a1 second is 1
first is a2 second is 2
first is a3 second is 3
first is a4 second is

现在,我需要将上述命令包含在bash -c 中,因为它将通过kubectl exec 执行。它没有按预期工作,只评估它在最后一行解析的内容:

$ bash -c "while read -r first second; do echo first is $first second is $second; done < myfile"
first is a4 second is
first is a4 second is
first is a4 second is
first is a4 second is

这里缺少什么?

谢谢!

【问题讨论】:

    标签: bash shell parsing line


    【解决方案1】:

    您的参数在父 shell 中扩展,更改您的引号或转义参数扩展:

    $ bash -c 'while read -r first second; do echo first is $first second is $second; done < myfile'
    

    $ bash -c "while read -r first second; do echo first is \$first second is \$second; done < myfile"
    

    请注意,您几乎应该始终将参数扩展用双引号括起来:

    echo "$a"
    

    而不是

    echo $a
    

    为了避免分词和路径名扩展。

    考虑以下示例,在 POSIX shell 中:

    a="hello *"; echo $a;
    

    a="hello *"; echo "$a";
    

    所以这会让你的脚本最终看起来像:

    $ bash -c 'while read -r first second; do echo first is "$first" second is "$second"; done < myfile'
    

    【讨论】:

      【解决方案2】:

      如果您不想处理复杂的 shell 双引号,首先定义一个函数,您可以在其中手动输入代码,shellcheck 也可以帮助您输入正确的代码:

      f() { 
         while IFS=' ' read -r first second; do
              echo "first is $first second is $second";
         done
      } 
      

      然后做:

      printf "%q\n" "$(declare -f f); f"
      $'f () \n{ \n    while IFS=\' \' read -r first second; do\n        echo "first is $first second is $second";\n    done\n}; f'
      

      declare 以可重复使用的形式打印函数定义,然后f 调用该函数。然后你可以复制输出并在 shell 中重新使用它:

      bash -c $'f () \n{ \n    while IFS=\' \' read -r first second; do\n        echo "first is $first second is $second";\n    done\n}; f'
      

      $'...' 特定于 Bash C 引用样式,因此在需要时使用与 printf %q 不同的引用函数。

      【讨论】:

      • 这是一个生成实际代码的好技巧。
      猜你喜欢
      • 1970-01-01
      • 2014-09-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-10-01
      • 1970-01-01
      相关资源
      最近更新 更多