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

发布于 2024-10-25 18:59:03 字数 846 浏览 2 评论 0原文

我刚刚编写了一个 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 文件内容,因为我正在处理每年可能更改一次或两次的表),我'我很好奇将查询结果放入变量而不是文件中的可能性。

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

echo -e "some\tstring\n"

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

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

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

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:

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=

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.

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 cat with echo -e). I tried this:

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?

\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.

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:

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 cat with echo -e). I tried this:

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

别忘他 2024-11-01 18:59:03

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

请注意,一旦输出位于变量中,如果您需要保留 $IFS 中的任何内容,则无论在何处使用它,都可能需要(双)引用它。

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

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.

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.

$ listing="$(ls -l)"
$ echo "$listing"
一世旳自豪 2024-11-01 18:59:03

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

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

心欲静而疯不止 2024-11-01 18:59:03
% 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 和类似方法迭代变量。

-麦克风

% 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>

You might get some use out of this. The heredoc should obviate any escaping issues, awk will separate on tabs by default, and set accepts the input as a builtin argv array. printf isn't necessary, but it's better than echo - especially when working with escape characters.

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

-Mike

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文