Bash 如何将特定分隔符之间的文本捕获到shell变量中?
我在指定变量方面没有什么问题。我有一个包含普通文本的文件,文件中的某个地方有括号Bash 如何将特定分隔符之间的文本捕获到shell变量中?,bash,unix,variables,Bash,Unix,Variables,我在指定变量方面没有什么问题。我有一个包含普通文本的文件,文件中的某个地方有括号[](整个文件中只有一对括号),它们之间有一些文本。我需要在shell(bash)变量中捕获这些括号内的文本。请问我该怎么做?Bash/sed: VARIABLE=$(tr -d '\n' filename | sed -n -e '/\[[^]]/s/^[^[]*\[\([^]]*\)].*$/\1/p') 如果这是不可读的,这里有一点解释: VARIABLE=`subexpression` Assig
[]
(整个文件中只有一对括号),它们之间有一些文本。我需要在shell(bash)变量中捕获这些括号内的文本。请问我该怎么做?Bash/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
那么:
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
”表示:
- 对于包含开放式括号和封闭式括号的任何行
- 取代了由“字符到打开括号”、“字符最多但不包括紧括号”(并记住这一点)、“中间括号内的字符”和“中间字符”和 组成的模式。
- 打印结果
$ 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
$
对于单线情况:
$ 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完成整个工作变得更为简单,在两个多行替换操作中对文件进行slurp处理并编辑结果字符串。假设您询问的是bash变量:
$ export YOUR_VAR=$(perl -ne'print $1 if /\[(.*?)\]/' your_file.txt)
如果括号在同一行上,上述方法也能起作用。感谢大家,我使用了Strager的版本,效果非常好,再次感谢大家
var=`grep -e '\[.*\]' test.txt | sed -e 's/.*\[\(.*\)\].*/\1/' infile.txt`
var=`grep -e '\[.*\]' test.txt | sed -e 's/.*\[\(.*\)\].*/\1/' infile.txt`
Sed是不必要的:
var=`egrep -o '\[.*\]' FILENAME | tr -d ][`
但它只适用于单线匹配 请允许我指出,虽然大多数建议的解决方案都可能有效,但绝对没有理由让您派生另一个shell,并生成多个进程来完成如此简单的任务 shell为您提供了所需的所有工具:
$ var='foo[bar] pinch'
$ var=${var#*[}; var=${var%%]*}
$ echo "$var"
bar
- 见:
var='foo[bar] pinch'
[[ "$var" =~ [^\]\[]*\[([^\[]*)\].* ]] # Bash 3.0
var="${BASH_REMATCH[1]}"
echo "$var"
反斜杠(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"
提取文本的2个简单步骤
你是说一个shell变量吗?你在用Bash吗?忘了提,是的,在离我很近的Bash中-你忘了带文件名@莱夫勒,噢,谢谢!我在测试中得到了它,但在解决方案中遗漏了它;我已经有了一个解决方案[在一条线路上]和另一条线路上。如何组合这两个工作?@乔纳森:在Perl中它是微不足道的(它也适用于多个非重叠括号):Perl - 0777 Ne'Perfices 1美元//[(.*])/GS’in FIL.TXTT请考虑使用$()而不是``。它与POSIX兼容,并且更易于阅读和消除歧义。一旦超过某一点,Perl就会比sed更容易。如果要问为什么在给出这些信息的情况下,Strager的版本没有被选为“答案”,这是不合理的吗?是否可以将这三行改为四行?即,是否可以使用此方法从两端剥离,而无需再次分配$var?