shell脚本,在awk中设置一个变量,然后将其用于脚本的其余部分

时间:2015-04-07 19:29:09

标签: shell awk

echo $fbname | awk -F'[__]' '{print $2 $A_name = $2}'
echo $A_name

我试图在fbname变量中提取一个名称,例如, newlist_sammy_card.csv所以我试图获得两个下划线之间的名称sammy,并将其分配给我可用于其余脚本的变量。

第一行打印出sammy,这是我需要的,但第二行没有。

有人能告诉我我在哪里没有正确地确定变量吗?

4 个答案:

答案 0 :(得分:4)

您的理解和推理存在根本缺陷。如果您在脚本中调用awk,则会根据自己的个人权利将其作为程序生成。因此,当前shell中存在的所有变量都不可用于awk,反之亦然。因此,您无法定义' awk中的变量,然后您的shell可见。你应该做的是捕获' awk的输出,使用符号$(),并将其分配给变量。考虑这个例子:

var=$(awk '{print "test"}')
echo $var

这将输出

test

现在,在您的情况下,我们实际上面临xy-problem。您想从字符串sammy中提取newlist_sammy_card.csv并将其用作变量。纯粹bash的一个可能的解决方案如下:

name="newlist_sammy_card.csv"
temp=${name#*_}
var=${temp%%_*}
echo $var

这将输出

sammy

答案 1 :(得分:2)

您只需使用bash

即可
str1="newlist_sammy_card.csv"

# replace 'newlist_' from front of the string
str2=${str1#*_}

# replace '_card.csv' from back of the string:
str2=${str2%%_*}

echo "$str2" # Output: sammy

不幸的是,它无法在bash的单次运行中完成。但是它应该比启动任何类型的外部程序都要好得多。

答案 2 :(得分:2)

有很多方法可以满足您的需求,例如:除了你到目前为止收到的其他想法之外,还有几个:

$ fbname='newlist_sammy_card.csv'

$ A_name=$(echo "$fbname" | cut -d_ -f2)
$ echo "$A_name"
sammy

或:

$ IFS=_
$ set -- $fbname
$ A_name="$2"
$ echo "$A_name"
sammy

但我想知道你是否完全以错误的方式接近你的问题。如果没有更多关于你想要做什么的信息,我们无法分辨。

答案 3 :(得分:1)

Pankrates's answer很好地解释了OP方法的问题,并提供了使用shell参数扩展的纯shell解决方案。

这是另一个纯shell解决方案,使用基于 read 内置的单一命令

使用bash,带有here-string:

IFS=_ read -r _ A_name _ <<<"$fbname"

与POSIX兼容,使用here-doc:

IFS=_ read -r _ A_name _ <<EOF
$fbname
EOF

如果$fbname包含'newlist_sammy_card.csv'$A_name之后将包含'sammy'

  • IFS=_告诉read_实例的输入拆分为令牌。
    • 请注意,通过直接将IFS=...添加到read,将$IFS设置为本地化read命令的效果 - 无需稍后恢复原始$IFS
  • read -r _ A_name _ ...读取未修改的输入(-r - 没有反斜杠转义序列的解释)
    • 请注意,_两侧的A_name虚拟变量的 - 惯用 - 名称,用于输入不感兴趣,但需要定位提取感兴趣的令牌 在这种情况下,这只是巧合,这个虚拟变量的名称与$IFS字符相同。
    • 在这种情况下:$_接收第一个字段(在输入中第一个_字符之前),然后在第二个字段之后覆盖任何剩余字段,其中第二个字段是读入感兴趣的变量$A_name