如何处理包含“;”的变量?

发布于 2024-12-04 21:13:02 字数 947 浏览 0 评论 0原文

我有一个配置文件,其中包含诸如“hallo;welt;”之类的行我想对此文件执行 grep 操作。 每当我尝试诸如 grep "$1;$2" my.configecho "$1;$2 of even line="$1;$2" 之类的操作时,我的脚本都会失败,并显示以下内容:

:未找到命令95:第 155 行:=hallo...

我怎样才能告诉 bash 忽略 ;在评估“...”块时?

编辑:我的代码的示例。

# find entry
$line=$(grep "$1;$2;" $PERMISSIONSFILE)
# splitt line
reads=$(echo $line | cut -d';' -f3)
writes=$(echo $line | cut -d';' -f4)
admins=$(echo $line | cut -d';' -f5)

# do some stuff on the permissions

# replace old line with new line
nline="$1;$2;$reads;$writes;$admins"
sed -i "s/$line/$nline/g" $TEMPPERM

我的脚本应该这样调用: sh script "table" "ab*.>"

编辑:另一个更简单的示例

$test=$(grep "$1;$2;" temp.authorization.config)

临时文件:

table;pattern;read;write;stuff

调用 sh test.sh 表模式导致: : command not findtable;pattern;read;write;stuff

I have a configuration file that contains lines like "hallo;welt;" and i want to do a grep on this file.
Whenever i try something like grep "$1;$2" my.config or echo "$1;$2 of even line="$1;$2" my script fails with something like:

: command not found95: line 155: =hallo...

How can i tell bash to ignore ; while evaluating "..." blocks?

EDIT: an example of my code.

# find entry
$line=$(grep "$1;$2;" $PERMISSIONSFILE)
# splitt line
reads=$(echo $line | cut -d';' -f3)
writes=$(echo $line | cut -d';' -f4)
admins=$(echo $line | cut -d';' -f5)

# do some stuff on the permissions

# replace old line with new line
nline="$1;$2;$reads;$writes;$admins"
sed -i "s/$line/$nline/g" $TEMPPERM

my script should be called like this: sh script "table" "a.b.*.>"

EDIT: another, simpler example

$test=$(grep "$1;$2;" temp.authorization.config)

the temp file:

table;pattern;read;write;stuff

the call sh test.sh table pattern results in: : command not foundtable;pattern;read;write;stuff

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

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

发布评论

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

评论(4

橘虞初梦 2024-12-11 21:13:02

不要在 bash 中的赋值左侧使用 $ ——如果这样做,它将替换变量的当前值而不是赋值给它。也就是说,使用:

test=$(grep "$1;$2;" temp.authorization.config)

而不是:

$test=$(grep "$1;$2;" temp.authorization.config)

编辑:此外,变量扩展应该用双引号引起来,除非有充分的理由。例如,使用:

reads=$(echo "$line" | cut -d';' -f3)

代替:

reads=$(echo $line | cut -d';' -f3)

这对于分号来说并不重要,但对于空格、通配符和其他一些东西来说很重要。

Don't use $ on the left side of an assignment in bash -- if you do it'll substitute the current value of the variable rather than assigning to it. That is, use:

test=$(grep "$1;$2;" temp.authorization.config)

instead of:

$test=$(grep "$1;$2;" temp.authorization.config)

Edit: also, variable expansions should be in double-quotes unless there's a good reason otherwise. For example, use:

reads=$(echo "$line" | cut -d';' -f3)

instead of:

reads=$(echo $line | cut -d';' -f3)

This doesn't matter for semicolons, but does matter for spaces, wildcards, and a few other things.

决绝 2024-12-11 21:13:02

引号内的 ; 对于 bash 来说根本没有任何意义。但是,如果 $1 本身包含双引号,那么您最终将

grep "something";$2"

被 bash 解析为两个单独的命令:

grep "something"   ;     other"
^---command 1----^    ^----command 2---^

Show 请准确显示您的脚本在发生错误的地方正在做什么,以及您的数据重新喂进去。

A ; inside quotes has no meaning at all for bash. However, if $1 contains a doublequote itself, then you'll end up with

grep "something";$2"

which'll be parsed by bash as two separate commands:

grep "something"   ;     other"
^---command 1----^    ^----command 2---^

Show please show exactly what your script is doing around the spot the error is occurring, and what data you're feeding into it.

盗心人 2024-12-11 21:13:02

反例:

$ cat file.txt
hello;welt;
hello;world;
hell;welt;  
$ cat xx.sh
grep "$1;$2" file.txt
$ bash -x xx.sh hello welt
+ grep 'hello;welt' file.txt
hello;welt;
$

你还没有准确分类你的问题。


如果您尝试将 grep 的结果分配给变量(就像我一样),您的示例就会崩溃。

请表明你的意思。使用与之前相同的数据文件并进行分配,这是我得到的输出:

$ cat xx.sh
grep "$1;$2" file.txt
output=$(grep "$1;$2" file.txt)
echo "$output"
$ bash -x xx.sh hello welt
+ grep 'hello;welt' file.txt
hello;welt;
++ grep 'hello;welt' file.txt
+ output='hello;welt;'
+ echo 'hello;welt;'
hello;welt;
$

似乎对我有用。它还说明了为什么这个问题需要一个明确的、完整的、可执行的、最小的例子,这样我们就可以看到提问者正在做的事情与回答问题的人认为正在发生的事情不同。


我看到您提供了一些示例代码:

# find entry
$line=$(grep "$1;$2;" $PERMISSIONSFILE)
# splitt line
reads=$(echo $line | cut -d';' -f3)
writes=$(echo $line | cut -d';' -f4)
admins=$(echo $line | cut -d';' -f5)

$line=$(grep ...) 行是错误的。您应该省略 line 之前的 $。尽管它在语法上是正确的,但它的意思是“将 grep 命令的结果分配给名称存储在 $line 中的变量”。这不太可能是你的想法。有时它是有用的。然而,这种情况很少见,而且只适合那些知道自己在做什么并且能够准确记录自己在做什么的人。

为了安全起见,如果不出意外,我还会将 echo 行中的 $line 值括在双引号中。这可能不是严格必要的,但它是简单的保护性编程。

这些更改导致:

# find entry
line=$(grep "$1;$2;" $PERMISSIONSFILE)
# split line
reads=$( echo "$line" | cut -d';' -f3)
writes=$(echo "$line" | cut -d';' -f4)
admins=$(echo "$line" | cut -d';' -f5)

脚本的其余部分很好。

Counter-example:

$ cat file.txt
hello;welt;
hello;world;
hell;welt;  
$ cat xx.sh
grep "$1;$2" file.txt
$ bash -x xx.sh hello welt
+ grep 'hello;welt' file.txt
hello;welt;
$

You have not yet classified your problem accurately.


If you try to assign the result of grep to a variable (like I do) your example breaks.

Please show what you mean. Using the same data file as before and doing an assignment, this is the output I get:

$ cat xx.sh
grep "$1;$2" file.txt
output=$(grep "$1;$2" file.txt)
echo "$output"
$ bash -x xx.sh hello welt
+ grep 'hello;welt' file.txt
hello;welt;
++ grep 'hello;welt' file.txt
+ output='hello;welt;'
+ echo 'hello;welt;'
hello;welt;
$

Seems to work for me. It also demonstrates why the question needs an explicit, complete, executable, minimal example so that we can see what the questioner is doing that is different from what people answering the question think is happening.


I see you've provided some sample code:

# find entry
$line=$(grep "$1;$2;" $PERMISSIONSFILE)
# splitt line
reads=$(echo $line | cut -d';' -f3)
writes=$(echo $line | cut -d';' -f4)
admins=$(echo $line | cut -d';' -f5)

The line $line=$(grep ...) is wrong. You should omit the $ before line. Although it is syntactically correct, it means 'assign to the variable whose name is stored in $line the result of the grep command'. That is unlikely to be what you had in mind. It is, occasionally, useful. However, those occasions are few and far between, and only for people who know what they're doing and who can document accurately what they're doing.

For safety if nothing else, I would also enclose the $line values in double quotes in the echo lines. It may not strictly be necessary, but it is simple protective programming.

The changes lead to:

# find entry
line=$(grep "$1;$2;" $PERMISSIONSFILE)
# split line
reads=$( echo "$line" | cut -d';' -f3)
writes=$(echo "$line" | cut -d';' -f4)
admins=$(echo "$line" | cut -d';' -f5)

The rest of your script was fine.

说不完的你爱 2024-12-11 21:13:02

您似乎正在尝试读取以分号分隔的文件,识别以“table;pattern;”开头的行其中 table 是您指定的字符串,pettern 是 grep 能够理解的正则表达式。识别该行后,您希望用不同的数据替换第三、第四和第五字段,并将更新后的行写回到文件中。

这听起来正确吗?

如果是这样,请尝试我选择在此处按行号更新的代码

#!/bin/bash

in_table="$1"
in_pattern="$2"
file="$3"

while IFS=';' read -r -d

,以避免替换左侧出现未知字符的问题。

\n' tuple pattern reads writes admins ; do line=$(cut -d: -f1<<<"$tuple") table=$(cut -d: -f2<<<"$tuple") # do some stuff with the variables # e.g., update the values reads=1 writes=2 admins=12345 # replace the old line with the new line sed -i'' -n $line'{i\ '"$table;$pattern;$reads;$writes;$admins"' ;d;}' "$file" done < <(grep -n '^'"${in_table}"';'"${in_pattern}"';' "${file}")

,以避免替换左侧出现未知字符的问题。

It seems like you are trying to read a semicolon-delimited file, identify a line starting with 'table;pattern;' where table is a string you specify and pettern is a regular expression grep will understand. Once the line is identified you wish to replaced the 3rd, 4th and 5th fields with different data and write the updated line back to the file.

Does this sound correct?

If so, try this code

#!/bin/bash

in_table="$1"
in_pattern="$2"
file="$3"

while IFS=';' read -r -d

I chose to update by line number here to avoid problems of unknown characters in the left hand of the substitution.

\n' tuple pattern reads writes admins ; do line=$(cut -d: -f1<<<"$tuple") table=$(cut -d: -f2<<<"$tuple") # do some stuff with the variables # e.g., update the values reads=1 writes=2 admins=12345 # replace the old line with the new line sed -i'' -n $line'{i\ '"$table;$pattern;$reads;$writes;$admins"' ;d;}' "$file" done < <(grep -n '^'"${in_table}"';'"${in_pattern}"';' "${file}")

I chose to update by line number here to avoid problems of unknown characters in the left hand of the substitution.

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