在bash中构建一个由2个子变量组成的变量

时间:2019-01-30 22:27:58

标签: bash sed

这是我使用的脚本:

for dir in $(find . -type d -name "single_copy_busco_sequences"); do  
    sppname=$(dirname $(dirname $(dirname $dir))| sed 's@./@@g');
    for file in ${dir}/*.faa; do name=$(basename $file); cp $file /Users/admin/Documents/busco_aa/${sppname}_${name}; sed -i '' 's@>@>'${sppname}'|@g' /Users/admin/Documents/busco_aa/${sppname}_${name}; cut -f 1 -d ":" /Users/admin/Documents/busco_aa/${sppname}_${name} > /Users/admin/Documents/busco_aa/${sppname}_${name}.1;
    done;
done

sppname变量类似于Gender_species 您知道我如何在脚本中添加一行以创建一个名为abbrev的新变量,该变量将Gender_species转换为Genspe,the 3 first letters猫,其中3 first字母位于_

之后

示例:

Homo_sapiens gives Homsap
Canis_lupus gives Canlup

感谢您的帮助:)

2 个答案:

答案 0 :(得分:2)

您可以使用带有sed的正则表达式来实现此目的:

echo "Homo_sapiens" | sed -e s'/^\(...\).*_\(...\).*/\1\2/'
Homsap

开始,得到3个字符(保持在\ 1),_,任何东西,得到3个字符(保持在\ 2),任何东西

用$ dir替换回声“ Homo_sapiens”

PS:如果每个单词少于3个字符,则失败

答案 1 :(得分:1)

您可以使用bash内置的参数扩展完成所有操作。具体来说,字符串索引子字符串删除

$ a=Homo_sapiens; prefix=${a:0:3}; a=${a#*_}; postfix=${a:0:3}; echo $prefix$postfix
Homsap

$ a=Canis_lupus; prefix=${a:0:3}; a=${a#*_}; postfix=${a:0:3}; echo $prefix$postfix
Canlup

使用bash内置的方法总是比生成单独的子shell来调用实用程序来完成相同任务的效率更高。

说明

您的字符串索引格式(仅用于bash)可让您从字符串中为字符编制索引,例如

* ${parameter:offset:length}  ## indexes are zero based, ${a:0:2} is 1st 2 chars

parameter只是包含字符串的变量名。

(您可以使用负偏移量从字符串的末尾开始索引,该负偏移量后跟space或用括号括起来,例如a=12345; echo ${a: -3:2}输出"34"

    prefix=${a:0:3}   ## save the first 3 characters in prefix
    a=${a#*_}         ## remove the front of the string through '_' (see below)
    postfix=${a:0:3}  ## save the first 3 characters after '_'

您的子字符串删除表格(POSIX)是:

  • ${parameter#word}从左边的参数中修剪到单词的第一个出现
  • ${parameter##word}修剪从参数左起最后出现的单词

  • ${parameter%word}从右边的参数中修剪到单词的第一个出现
  • ${parameter%%word}从右边的参数中修剪到最后出现的单词

单词也可以包含球形符号以扩展为模式)

   a=${a#*_}   ## trim from left up to (and including) the first '_'

有关详细信息,请参见bash(1) - Linux manual page