将反斜杠转义的字符保存到 bash 中的变量

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5393101/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-17 23:39:12  来源:igfitidea点击:

Saving backslash-escaped characters to variable in bash

bashescaping

提问by mingos

I've just written a bash script that takes some info from the mysql database and reads it line by line, extracting tab-separated columns into separate variables, something like this:

我刚刚编写了一个 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

Now, while this works OK and I'm satisfied with the result (especially since I'm going to move the query t oanother script and let cron regenerate the result.txt file contents once a week or so, since I'm dealing with a table that changes maybe once or twice a year), I'm curious about the possibility of putting the query's result in a variable instead of a file.

现在,虽然这工作正常并且我对结果感到满意(特别是因为我要将查询移动到另一个脚本并让 cron 每周重新生成一次 result.txt 文件内容,因为我正在处理一个每年可能更改一次或两次的表),我很好奇将查询结果放在变量而不是文件中的可能性。

I have noticed that in order to echo out backslash-excaped characters, I need to tell the command explicitly to interpret such characters as special chars:

我注意到为了回显出反斜杠转义字符,我需要明确地告诉命令将这些字符解释为特殊字符:

echo -e "some\tstring\n"

But, being a bash noob that I am, I have no idea how to place the backslash escaped characters (the tabs and newlines from the query) inside a variable and just work with it the same way I'm working with the external file (just changing the catwith echo -e). I tried this:

但是,作为一个 bash 菜鸟,我不知道如何将反斜杠转义字符(查询中的制表符和换行符)放置在变量中,并以与处理外部文件相同的方式使用它(只是改变了catecho -e)。我试过这个:

result=`$mysql -e "SELECT id,foo,bar,baz FROM $db.$table" -u $user --password=$pass -h $server`

but the backslash escaped characters are converted into spaces this way :(. How can I make it work?

但是反斜杠转义字符以这种方式转换为空格:(。我怎样才能让它工作?

回答by bobbogo

To get the output of a command, use $(...). To avoid wordsplitting and other bash processing you will need to quote. Single quotes ('$(...)') will not work as the quoting is too strong.

要获取命令的输出,请使用$(...). 为避免分词和其他 bash 处理,您需要引用。单引号 ( '$(...)') 将不起作用,因为引用太强了。

Note that once the output is in your variable, you will probably need to (double) quote it wherever you use it if you need to preserve anything that's in $IFS.

请注意,一旦输出在您的变量中,如果您需要保留$IFS.

$ listing="$(ls -l)"
$ echo "$listing"

回答by bmk

Could you try to set double quotes around $result- thus echo -e "$result"?

您可以尝试在周围设置双引号$result- 因此echo -e "$result"

回答by mikeserv

% awk '/^[0-9]/ { print , , ,  }' <<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>

You might get some use out of this. The heredocshould obviate any escaping issues, awkwill separate on tabs by default, and setaccepts the input as a builtin argvarray. printfisn't necessary, but it's better than echo- especially when working with escape characters.

你可能会从中得到一些用处。在heredoc应该避免任何逸出的问题,awk将默认上分离的标签,并且set接受输入作为内置argv阵列。printf不是必需的,但它比echo- 特别是在使用转义字符时更好。

You could also use readas you did above - but to better handle backslashes use the -rargument if you go that route. The above method would work best as a function and you could then iterate over your variables with shiftand similar.

您也可以read像上面那样使用- 但是-r如果您走那条路,请使用参数更好地处理反斜杠。上述方法最适合作为函数使用,然后您可以使用shift和 类似的方法迭代变量。

-Mike

-麦克风