我刚刚编写了一个bash脚本,它从mysql数据库获取一些信息并逐行读取,将制表符分隔的列提取为单独的变量,如下所示:
oldifs=$IFS
result=result.txt
$mysql -e "SELECT id,foo,bar,baz FROM $db.$table" -u $user --password=$pass -h $server > $result
cat $result | grep -e ^[0-9].*$ | while IFS=$'\t' read id foo bar baz
do
# some code
done
IFS=$oldifs
现在,虽然这个工作正常但我对结果感到满意(特别是因为我要将查询移到另一个脚本上,让cron每周重新生成一次result.txt文件内容,因为我'在处理一年一次或两次更改的表时,我很好奇将查询结果放在变量而不是文件中的可能性。
我注意到为了回显反斜杠 - excaped字符,我需要明确告诉命令将这些字符解释为特殊字符:
echo -e "some\tstring\n"
但是,作为一个bash noob,我不知道如何将反斜杠转义字符(查询中的制表符和换行符)放在变量中,只需使用它就像我使用它一样外部文件(仅使用cat
更改echo -e
)。我试过这个:
result=`$mysql -e "SELECT id,foo,bar,baz FROM $db.$table" -u $user --password=$pass -h $server`
但是反斜杠转义字符会以这种方式转换为空格:(。我怎样才能使它工作?
答案 0 :(得分:2)
要获取命令的输出,请使用$(...)
。为避免单词分词和其他bash处理,您需要引用。单引号('$(...)'
)不起作用,因为引用过于强烈。
请注意,一旦输出在您的变量中,如果您需要保留$IFS
中的任何内容,您可能需要(双)引用它,无论您何时使用它。
$ listing="$(ls -l)"
$ echo "$listing"
答案 1 :(得分:1)
您是否可以尝试在$result
周围设置双引号 - 因此echo -e "$result"
?
答案 2 :(得分:0)
% awk '/^[0-9]/ { print $2, $3, $4, $5 }' <<SQL | set -- -
> $("${mysql}" -e "SELECT id,foo,bar,baz FROM $db.$table" -u $user --password=$pass -h $server)
> SQL
% printf '%s\t' "${@}"
<id> <foo> <bar> <baz>
你可能会得到一些用处。 heredoc
应该避免任何转义问题,awk
默认会在标签上分开,set
接受输入作为内置argv
数组。 printf
不是必需的,但它比echo
更好 - 尤其是在使用转义字符时。
您也可以像上面那样使用read
- 但是为了更好地处理反斜杠,如果你走这条路线,请使用-r
参数。上述方法最适合作为函数,然后您可以使用shift
和类似的方法迭代变量。
-Mike