在tail命令中使用变量

时间:2019-04-02 04:49:36

标签: bash tail

我正在尝试从参考文件中导出字符,这些文件的字节位置已知。为此,我有一长串数字存储为变量,这些数字已用作尾命令的输入。

例如,参考文件如下:

ggaaatgcattcaaacatgc

列表如下:

5
10
7
15

我尝试使用此代码:

list=$(<pos.txt)
echo "$list"
cat ref.txt | tail -c +"list" | head -c1 > out.txt

但是,它不断返回“无效的字节数:'+ 5 \ n10 \ n7 \ n15 ...'”

我的预期输出是

a
t
g
a
... 

有人可以告诉我我在做什么错吗?谢谢!

3 个答案:

答案 0 :(得分:3)

您似乎正在尝试在tail命令中访问list变量。您可以这样访问它:$list,而不仅仅是使用引号引起来。

即使修复了变量访问后,您的逻辑也有缺陷。 list变量包括list.txt文件的所有行。包括换行符\n,它在许多UI和程序中都不可见,但是当您手动读取单个字节时,它当然是可见的。您需要一行一行地填充,以使其正常工作。

此外,除非这些数字是末尾的索引,否则您需要将它们送入头部而不是尾部。

如果我了解您要正确执行的操作,则应该可以:

while read line
do
  head -c $line ref.txt | tail -c 1 >> out.txt
done < pos.txt

答案 1 :(得分:2)

命令失败的原因很简单。变量list包含从pos.txt文件存储的多行字符串,包括换行符。您不能为-c标志传递不超过一个整数值。

通过删除对cat的调用并使用临时变量来保存文件内容,可以很轻松地解决您的尝试

while IFS= read -r lineNo; do
    tail -c "$lineNo" ref.txt | head -c1
done < pos.txt

但是,如果您的意图是每次都用换行符打印所需的输出,则head不会以这种方式输出。它只是在一行中为给定的输入形成一个字符串atga,在多行中不是,每行各有一个字符。

正如戈登在评论中提到的那样,为了更有效地处理FASTA文件,您可以只使用一次对awk的调用(将多个派生跳过到head / tail) 。您提供的输入不包含任何要跳过的标头,因为

awk ' FNR==NR{ n = split($0,arr,""); for(i=1;i<=n;i++) hash[i] = arr[i] } 
      ( $0 in hash ){ print hash[$0] } ' ref.txt pos.txt

答案 2 :(得分:1)

您可以使用webView.Source = new HtmlWebViewSource { Html = "<iframe src=\"https://www.youtube.com/embed/" + data + "\" frameborder=\"0\" allowfullscreen=\"false\"></iframe>" }; 代替cut

tail

或者只是awk:

pos=$(<pos.txt)
cut -c ${pos//$'\n'/,} --output-delimiter=$'\n' ref.txt

两者都是

awk -F '' 'NR==FNR{c[$0];next} {for(i in c) print $i}' pos.txt ref.txt