bash变量中的星号

问题描述 投票:0回答:2

我有一个文件,其中包含我正在检索的信息

命令

cat 2018_02_15_09_01_08_result.tsv | grep -o [A-Z]\\*[0-9]*:[0-9]* | sort | uniq | sed -e 's/^/HLA-/'  |tr '\n' ',' | sed '$ s/.$//'

产量

HLA-A*30:02,HLA-B*18:01,HLA-C*05:01

但我试图将其保存在变量中,星号和字母消失,我尝试了几种方法,添加/删除逗号等,但我还是无法正确打印它。

hla=`cat 2018_02_15_09_01_08_result.tsv | grep -o [A-Z]\\*[0-9]*:[0-9]* | sort | uniq | sed -e 's/^/HLA-/'  |tr '\n' ',' | sed '$ s/.$//'`

echo $hla
HLA-05:01,HLA-18:01,HLA-30:02
echo "$hla"
HLA-05:01,HLA-18:01,HLA-30:02
bash shell
2个回答
2
投票

这里存在多个错误,其中大多数错误将由http://shellcheck.net/恰当地诊断,无需任何人为干预。

  • 除非您在执行命令之前特别要求shell在正则表达式上执行通配符扩展和空白标记化,否则您应该单引用正则表达式。
  • 反引号中过时的`command`在反引号内的字符串上引入了一些不幸的额外shell处理。自20世纪90年代以来的解决方案是更喜欢使用$(command)语法进行命令替换,但这并没有出现这个问题。
  • cat is useless; grep非常了解如何阅读文件。

试试这个重构的代码:

hla=$(grep -o '[A-Z]*[0-9]*:[0-9]*' 2018_02_15_09_01_08_result.tsv |
  sort -u | sed -e 's/^/HLA-/'  |tr '\n' ',' | sed '$ s/.$//')
echo "$hla"

echo中变量插值周围的双引号是necessary and useful;另请注意,线条包含易读性和使用sort -u优先于sort | uniq(并且通常会尝试减少进程的数量 - 一旦我理解了sed | tr | sed的作用,我也可以提出简化)。也许最简单的解决方法是将所有这些重构为单个Awk脚本,但如果无法访问输入,则很难更详细地告诉您这可能是什么样子。

(另外,你真的确定你需要将值捕获到一个变量吗?通常variable=value; echo "$variable"只是一种模糊和低效的方式来说echo "value"。而variable=$(command); echo "$variable"更好地编写简单的command并捕获命令的标准输出只是为了你可以将它打印到标准输出是纯粹的循环浪费,除非你打算用这个变量的值做更多的事情。)


-1
投票

我通过重定向保存命令的输出来解决它:

cat 2018_02_15_09_01_08_result.tsv |
grep -o [A-Z]\\*[0-9]*:[0-9]* |
sort | uniq |
sed -e 's/^/HLA-/'  |tr '\n' ',' | sed '$ s/.$//' > out_file
hla=`cat out_file`
echo $hla

这让我得到了预期的HLA-A*30:02,HLA-B*18:01,HLA-C*05:01。不是理想的解决方案,但它确实有效。

© www.soinside.com 2019 - 2024. All rights reserved.