首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在剪切命令中循环可变范围

如何在剪切命令中循环可变范围
EN

Stack Overflow用户
提问于 2017-11-07 17:49:14
回答 4查看 2.6K关注 0票数 5

我有一个有2列的文件,我想使用第二列中的值来设置剪切命令中的范围,以便从另一个文件中选择一个字符范围。我想要的范围是在第二列值的位置加上后面的10个字符的字符。我稍后会举一个例子。

我的档案就是这样的:

具有2列且行间没有空行的文件(file1.txt):

代码语言:javascript
复制
NAME1 10
NAME2 25
NAME3 48
NAME4 66

文件(file2.txt),该文件要提取字符的可变范围(只有一行很长,没有空格,也没有粗体字体):

GATCGAGCGGGATTCTTTTTTTTTAGGCGAGTCAGCTAGCATCAGCTACGAGAGGCGAGGGCGGGCTATCACGACTACGACTACGACTACAGCATCAGCATCAGCGCACTAGAGCGAGGCTAGCTAGCTACGACTACGATCAGCATCGCACATCGACTACGATCAGCATCAGCTACGCATCGAAGAGAGAGC

...or,更确切地说(用于复制/粘贴测试):

代码语言:javascript
复制
GATCGAGCGGGATTCTTTTTTTTTAGGCGAGTCAGCTAGCATCAGCTACGAGAGGCGAGGGCGGGCTATCACGACTACGACTACGACTACAGCATCAGCATCAGCGCACTAGAGCGAGGCTAGCTAGCTACGACTACGATCAGCATCGCACATCGACTACGATCAGCATCAGCTACGCATCGAAGAGAGAGC

所需的结果文件,每行(result.txt):一个序列

代码语言:javascript
复制
GATTCTTTTT
GGCGAGTCAG
CGAGAGGCGA
TATCACGACT

生成的文件将有从10-20,25-35,48-58和66-76字符,每一个范围在一个新的行。因此,它始终保持在10的范围内,但是在不同的起始点和这些起始点是由第一个文件的第二列中的值设置的。

我试过命令:

代码语言:javascript
复制
for i in $(awk '{print $2}' file1.txt);
do
        p1=$i;
        p2=`expr "$1" + 10`
        cut -c$p1-$2 file2.txt > result.txt;
done

我没有得到任何输出或错误信息。

我也试过:

代码语言:javascript
复制
while read line; do
    set $line
    p2=`expr "$2" + 10`
    cut -c$2-$p2 file2.txt > result.txt;
done <file1.txt

最后一个命令给出了一个错误消息:

代码语言:javascript
复制
cut: invalid range with no endpoint: -
Try 'cut --help' for more information.
expr: non-integer argument
EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2017-11-07 18:21:29

这里不需要cutdd可以对文件进行索引,并且只读取所需的字节数。(请注意,status=none是一个GNUism;如果要禁止信息日志记录,则可能需要将它排除在其他平台之外,并重定向stderr )。

代码语言:javascript
复制
while read -r name index _; do
  dd if=file2.txt bs=1 skip="$index" count=10 status=none
  printf '\n'
done <file1.txt >result.txt

这种方法避免了过多的内存需求(在读取整个file2时--假设它很大),并且具有有限度的性能要求(开销等于每个序列启动一个dd副本来提取)。

票数 4
EN

Stack Overflow用户

发布于 2017-11-07 18:28:26

使用awk

代码语言:javascript
复制
$ awk 'FNR==NR{a=$0; next} {print substr(a,$2+1,10)}' file2 file1
GATTCTTTTT
GGCGAGTCAG
CGAGAGGCGA
TATCACGACT
票数 3
EN

Stack Overflow用户

发布于 2017-11-07 18:26:11

如果file2.txt 不太大,则可以在内存中读取它,并使用Bash子字符串提取所需的范围:

代码语言:javascript
复制
data=$(<file2.txt)
while read -r name index _; do
  echo "${data:$index:10}"
done <file1.txt >result.txt

这将比对每个范围定义运行cut或其他进程更有效。

(感谢@CharlesDuffy让提示阅读没有无用catdata,以及while循环。)

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/47164363

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档