1

我有多个 fasta 文件,其中第一行总是包含>带有多个单词的 a,例如:

File_1.fasta: 
>KY620313.1 Hepatitis C virus isolate sP171215 polyprotein gene, complete cds
File_2.fasta: 
>KY620314.1 Hepatitis C virus isolate sP131957 polyprotein gene, complete cds
File_3.fasta: 
>KY620315.1 Hepatitis C virus isolate sP127952 polyprotein gene, complete cds

我想sP*从每个文件中取单词并将每个文件重命名为这个字符串(例如:File_1.fasta 到 sP171215.fasta)。到目前为止,我有这个:

    $ for match in "$(grep -ro '>')";do
          fname=$("echo $match|awk '{print $6}'")
          echo mv "$match" "$fname"
      done

但它不起作用,我总是得到错误:

grep:警告:递归搜索标准输入

我希望你能帮帮我!

4

4 回答 4

1

这段代码发生了几件事。首先,..我实际上没有得到这个特定的错误,这可能是由于不同的版本。它可能会解决 grep 的解释与bash 扩展做得不好的事实'>'相同的问题。>我建议也许去"\>"

第二:

fname=$("echo $match|awk '{print $6}'") 里面的引号起到了意想不到的作用。如果有的话,您的代码应该是这样的: fname="$(echo $match|awk '{print $6}')"

最后,为了正确检索您的数据,这应该是您的最终代码:

for match in "$(grep -Hr "\>")"; do
  fname="$(echo "$match" | cut -d: -f1)"
  new_fname="$(echo "$match" | grep -o "sP[^ ]*")".fasta
  echo mv "$fname" "$new_fname"
done

说明: grep -H-> 您希望您的 grep 显式使用“包含文件名”,以防万一其他 shell 环境决定别名grepgrep -h (no filenames)

您不想进行grep -o文件搜索,因为您希望在一个数据条目中同时包含文件名和“新文件名”。

虽然,我不明白你为什么要搜索'>'而不是'sP'的目录:

for match in "$(grep -Hro "sP[0-9]*")"

这不是完全相同的行为,并且有不同的边缘情况,但它可能对你有用。

于 2020-09-20T10:42:28.583 回答
1

你可以使用这样的东西:

grep '>' *.fasta | while read -r line ; do
  new_name="$(echo $line | cut -d' ' -f 6)"
  old_name="$(echo $line | cut -d':' -f 1)"
  mv $old_name "$new_name.fasta"
done
  1. 它搜索 *.fasta 文件并处理每个“命中”行
  2. 它用空格分割 grep 的每个结果,并将第 6 个元素作为新名称
  3. 它将 grep 的每个结果拆分为 : 并将第一个元素作为旧名称
  4. 它将旧文件名移动/重命名为新文件名
于 2020-09-20T10:45:56.717 回答
0

在 (g)awk 中非常简单:

创建一个文件“script.awk”:

FNR == 1 {
    for (i=1; i<=NF; i++) {
        if (index($i, "sP")==1) {
            print "mv", FILENAME, $i ".fasta"
            nextfile
        }
    }
}

用它 :

awk -f script.awk *.fasta > cmmd.txt

检查输出的内容。

mv File_1.fasta sP171215.fasta
mv File_2.fasta sP131957.fasta

如果可以,启动重命名. cmmd.txt

于 2020-09-20T11:00:17.100 回答
0

对于目录中的所有 fasta 文件,在它们的第一行中搜索第一个单词,sP并使用该单词作为基本名称重命名它们。

使用 bash 数组:

for f in *.fasta; do
    arr=( $(head -1 "$f") )
    for word in "${arr[@]}"; do
        [[ "$word" =~ ^sP* ]] && echo mv "$f" "${word}.fasta" && break
    done
done

或使用 grep:

for f in *.fasta; do
    word=$(head -1 "$f" | grep -o "\bsP\w*")
    [ -z "$word" ] || echo mv "$f" "${word}.fasta"
done

注意:echo测试没问题后删除。

于 2020-09-20T11:00:29.063 回答