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

在bash中构建一个由另一个变量的2个子Sting组成的变量,bash,sed,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/${sp

以下是我使用的脚本:

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\u species 你知道我如何在我的脚本中添加一行代码来创建一个名为abbrev的新变量,该变量将性别物种转换为Genspe,
3个首字母
cat和
后的
3个首字母

例如:

Homo_sapiens gives Homsap
Canis_lupus gives Canlup


感谢您的帮助:)

您可以使用带sed的正则表达式来实现这一点:

echo "Homo_sapiens" | sed -e s'/^\(...\).*_\(...\).*/\1\2/'
Homsap
开始,获取3个字符(保留在\1中),任意,\u,任意,获取3个字符(保留在\2中),任意

将echo“智人”替换为$dir


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

您可以使用bash内置的参数扩展来完成所有操作。特别是字符串索引和子字符串删除

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

解释

字符串索引表单(仅限bash)允许您从字符串中索引字符,例如

* ${parameter:offset:length}  ## indexes are zero based, ${a:0:2} is 1st 2 chars
其中,
参数
只是保存字符串的变量名

(您可以从字符串的末尾开始索引,方法是使用前面带有
空格的负偏移量
或用括号括起来,例如
a=12345;echo${a:-3:2}
输出
“34”

您的子字符串删除表单(POSIX)为:

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

  • ${parameter%word}
    从右边修剪到参数中第一个出现的单词
  • ${parameter%%word}
    从右侧修剪到参数中最后出现的单词
(word也可以包含globbing以扩展为模式)


有关详细信息,请参阅。

谢谢您的帮助:)哇,谢谢您提供的所有这些非常清晰的信息。您能抽出时间真是太好了!当然,很乐意帮忙。Bash提供了一整套简单而神奇的参数扩展,可以对sting执行任何需要执行的操作。只需要和他们交朋友。手册页中“参数扩展”下的整个部分都很好地解释了它们(尽管您可能只会定期使用一小部分,但当您发现自己陷入困境时,最好知道在哪里查找)。祝你的脚本编写工作好运。
* ${parameter:offset:length}  ## indexes are zero based, ${a:0:2} is 1st 2 chars
    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 '_'
   a=${a#*_}   ## trim from left up to (and including) the first '_'