如何将特定分隔符之间的文本捕获到shell变量中?

时间:2009-03-28 20:24:22

标签: bash unix variables

指定我的变量我没什么问题。我有一个普通文本的文件,其中有一个括号[ ](整个文件中只有一对括号),以及它们之间的一些文本。我需要在shell(bash)变量中捕获这些括号内的文本。我该怎么办?

10 个答案:

答案 0 :(得分:9)

击/ sed的:

VARIABLE=$(tr -d '\n' filename | sed -n -e '/\[[^]]/s/^[^[]*\[\([^]]*\)].*$/\1/p')

如果这是不可读的,这里有一点解释:

VARIABLE=`subexpression`      Assigns the variable VARIABLE to the output of the subexpression.

tr -d '\n' filename  Reads filename, deletes newline characters, and prints the result to sed's input

sed -n -e 'command'  Executes the sed command without printing any lines

/\[[^]]/             Execute the command only on lines which contain [some text]

s/                   Substitute
^[^[]*               Match any non-[ text
\[                   Match [
\([^]]*\)            Match any non-] text into group 1
]                    Match ]
.*$                  Match any text
/\1/                 Replaces the line with group 1
p                    Prints the line

答案 1 :(得分:6)

我可以指出,虽然大多数建议的解决方案都可行,但绝对没有理由为什么你应该分叉另一个shell,并产生几个进程来完成这么简单的任务。

shell为您提供了所需的所有工具:

$ var='foo[bar] pinch'
$ var=${var#*[}; var=${var%%]*}
$ echo "$var"
bar

答案 2 :(得分:3)

不需要Sed:

var=`egrep -o '\[.*\]' FILENAME | tr -d ][`

但它只适用于单线匹配。

答案 3 :(得分:2)

使用Bash内置正则表达式匹配似乎是另一种方法:

var='foo[bar] pinch'
[[ "$var" =~ [^\]\[]*\[([^\[]*)\].* ]]   # Bash 3.0
var="${BASH_REMATCH[1]}"
echo "$var"

答案 4 :(得分:1)

怎么样:

shell_variable=$(sed -ne '/\[/,/\]/{s/^.*\[//;s/\].*//;p;}' $file)

在Korn shell下的Solaris 10上为我工作;也应该与Bash合作。将“$(...)”替换为Bourne shell中的反向标记。

编辑:在[在一行上]和在另一行上给出时有效。对于单行情况,请使用:

shell_variable=$(sed -n -e '/\[[^]]*$/,/\]/{s/^.*\[//;s/\].*//;p;}' \
                        -e '/\[.*\]/s/^.*\[\([^]]*\)\].*$/\1/p' $file)

第一个'-e'涉及多线传播;第二个“-e”涉及单行案例。第一个“-e”说:

  • 从包含空心括号[的行中,后面没有紧密括号]
  • 直到包含右括号]
  • 的行
  • 用空字符串代替任何东西,包括空心字符串,
  • 用一个空字符串替换从右括号开始的任何内容,
  • 打印结果

第二个“-e”说:

  • 对于包含左括号和右括号的任何行
  • 替换由'包括开括号括起来的字符'组成的模式,'最多但不包括近括号'的字符(并记住这一点),'从近端括号开始的东西'与中间记住的字符,以及< / LI>
  • 打印结果

对于多行案例:

$ file=xxx
$ cat xxx
sdsajdlajsdl
asdajsdkjsaldjsal
sdasdsad [aaaa
bbbbbbb
cccc] asdjsalkdjsaldjlsaj
asdjsalkdjlksjdlaj
asdasjdlkjsaldja
$ shell_variable=$(sed -n -e '/\[[^]]*$/,/\]/{s/^.*\[//;s/\].*//;p;}' \
                          -e '/\[.*\]/s/^.*\[\([^]]*\)\].*$/\1/p' $file)
$ echo $shell_variable
aaaa bbbbbbb cccc
$

对于单行案例:

$ cat xxx
sdsajdlajsdl
asdajsdkjsaldjsal
sdasdsad [aaaa bbbbbbb cccc] asdjsalkdjsaldjlsaj
asdjsalkdjlksjdlaj
asdasjdlkjsaldja
$
$ shell_variable=$(sed -n -e '/\[[^]]*$/,/\]/{s/^.*\[//;s/\].*//;p;}' \
                          -e '/\[.*\]/s/^.*\[\([^]]*\)\].*$/\1/p' $file)
$ echo $shell_variable
aaaa bbbbbbb cccc
$

在这里的某个地方,在Perl中完成整个工作变得更简单,在两个多行替换操作中啜饮文件并编辑结果字符串。

答案 5 :(得分:1)

假设您在询问bash变量:

$ export YOUR_VAR=$(perl -ne'print $1 if /\[(.*?)\]/' your_file.txt)

如果括号在同一行,则上述情况有效。

答案 6 :(得分:0)

var=`grep -e '\[.*\]' test.txt | sed -e 's/.*\[\(.*\)\].*/\1/' infile.txt`

答案 7 :(得分:0)

感谢大家,我使用了Strager的版本并且工作得非常好,再次感谢...

var=`grep -e '\[.*\]' test.txt | sed -e 's/.*\[\(.*\)\].*/\1/' infile.txt`

答案 8 :(得分:0)

反斜杠(BSL)被碾碎......:

var='foo[bar] pinch' 
[[ "$var" =~ [^\]\[]*\[([^\[]*)\].* ]]   # Bash 3.0 
# Just in case ...: 
[[ "$var" =~ [^BSL]BSL[]*BSL[([^BSL[]*)BSL].* ]]   # Bash 3.0 
var="${BASH_REMATCH[1]}" 
echo "$var" 

答案 9 :(得分:0)

提取文本的2个简单步骤。

  1. 拆分[并获得正确的部分
  2. 拆分var at]并获取左侧部分
  3. cb0$ var='foo[bar] pinch'
    cb0$ var=${var#*[}
    cb0$ var=${var%]*} && echo $var
    bar