使用 bash -c 逐行解析
Line by line parsing with bash -c
在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
这里缺少什么?
谢谢!
您的参数在父级 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'
如果您不想处理复杂的 shell double-qouting,首先定义一个函数,您可以在其中手动输入代码,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
不同的引用函数。
在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
这里缺少什么?
谢谢!
您的参数在父级 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'
如果您不想处理复杂的 shell double-qouting,首先定义一个函数,您可以在其中手动输入代码,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
不同的引用函数。