bash变量中的星号

bash变量中的星号,bash,shell,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 但我试图将其保存在变量中,星号和字母消失,我尝试了几种方法,添加/删除逗号等,但我还无法正确打印

我有一个文件,其中包含我正在以这种方式检索的信息

命令

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

我已通过使用重定向保存命令的输出来解决此问题:

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
。这不是一个理想的解决方案,但它确实有效。

这里有多个错误,大多数错误都可以在没有任何人为干预的情况下通过诊断得到正确诊断

  • 除非您特别要求shell在执行命令之前对正则表达式执行通配符扩展和空格标记化,否则您确实应该单引号引用正则表达式

  • backticks中过时的
    `command`
    对backticks中的字符串引入了一些不幸的额外shell处理。20世纪90年代以来的解决方案是使用
    $(command)
    语法进行命令替换,这不会出现此问题

  • 第二
    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
中变量插值周围的双引号为;还要注意换行符的易读性和使用
sort-u
优先于
sort | uniq
(并且通常尝试减少进程的数量——一旦我了解了
sed | tr | sed
的作用,我可能也会提出一个简化方案)。也许最简单的修复方法是将所有这些重构为一个Awk脚本,但是如果没有对输入的访问权,很难更详细地告诉您这可能是什么样子


(另外,您真的确定需要将值捕获到变量中吗?通常
variable=value;echo“$variable”
只是说
echo“value”
variable=$(命令);echo“$variable”的一种模糊且低效的方式
最好是简单地编写
command
,捕获命令的标准输出以便将其打印到标准输出纯粹是浪费周期,除非您计划对该变量的值进行更多操作。)

显示输入文件的内容和预期输出,而不是一系列命令。我确信这可以用一种简单得多的方法来完成。
echo“$hla”
解决您的问题了吗?-->不,
echo“$hla”
不能解决我的问题,我已经试过了。谢谢,非常有用。
grep | sort
之后的输入类似于
HLA-A*30:02\n HLA-B*18:01 HLA-C*05:01
您可以用类似于
awk-F-”的内容替换从
sort
开始的整个管道!(a中的$2){a[$2];printf(“%s%s”,s,$2”);s=“,”}
(未经测试,但您明白了),但重构第一个
grep
可能并不难。