bash变量中的星号

时间:2018-02-28 09:15:05

标签: bash shell

我的文件包含我正在检索此类信息的信息

命令

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

2 个答案:

答案 0 :(得分: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 :(得分:-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。不是理想的解决方案,但它确实有效。