我有一个有2列的文件,我想使用第二列中的值来设置剪切命令中的范围,以便从另一个文件中选择一个字符范围。我想要的范围是在第二列值的位置加上后面的10个字符的字符。我稍后会举一个例子。
我的档案就是这样的:
具有2列且行间没有空行的文件(file1.txt):
NAME1 10
NAME2 25
NAME3 48
NAME4 66文件(file2.txt),该文件要提取字符的可变范围(只有一行很长,没有空格,也没有粗体字体):
GATCGAGCGGGATTCTTTTTTTTTAGGCGAGTCAGCTAGCATCAGCTACGAGAGGCGAGGGCGGGCTATCACGACTACGACTACGACTACAGCATCAGCATCAGCGCACTAGAGCGAGGCTAGCTAGCTACGACTACGATCAGCATCGCACATCGACTACGATCAGCATCAGCTACGCATCGAAGAGAGAGC
...or,更确切地说(用于复制/粘贴测试):
GATCGAGCGGGATTCTTTTTTTTTAGGCGAGTCAGCTAGCATCAGCTACGAGAGGCGAGGGCGGGCTATCACGACTACGACTACGACTACAGCATCAGCATCAGCGCACTAGAGCGAGGCTAGCTAGCTACGACTACGATCAGCATCGCACATCGACTACGATCAGCATCAGCTACGCATCGAAGAGAGAGC所需的结果文件,每行(result.txt):一个序列
GATTCTTTTT
GGCGAGTCAG
CGAGAGGCGA
TATCACGACT生成的文件将有从10-20,25-35,48-58和66-76字符,每一个范围在一个新的行。因此,它始终保持在10的范围内,但是在不同的起始点和这些起始点是由第一个文件的第二列中的值设置的。
我试过命令:
for i in $(awk '{print $2}' file1.txt);
do
p1=$i;
p2=`expr "$1" + 10`
cut -c$p1-$2 file2.txt > result.txt;
done我没有得到任何输出或错误信息。
我也试过:
while read line; do
set $line
p2=`expr "$2" + 10`
cut -c$2-$p2 file2.txt > result.txt;
done <file1.txt最后一个命令给出了一个错误消息:
cut: invalid range with no endpoint: -
Try 'cut --help' for more information.
expr: non-integer argument发布于 2017-11-07 18:21:29
这里不需要cut;dd可以对文件进行索引,并且只读取所需的字节数。(请注意,status=none是一个GNUism;如果要禁止信息日志记录,则可能需要将它排除在其他平台之外,并重定向stderr )。
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副本来提取)。
发布于 2017-11-07 18:28:26
使用awk
$ awk 'FNR==NR{a=$0; next} {print substr(a,$2+1,10)}' file2 file1
GATTCTTTTT
GGCGAGTCAG
CGAGAGGCGA
TATCACGACT发布于 2017-11-07 18:26:11
如果file2.txt 不太大,则可以在内存中读取它,并使用Bash子字符串提取所需的范围:
data=$(<file2.txt)
while read -r name index _; do
echo "${data:$index:10}"
done <file1.txt >result.txt这将比对每个范围定义运行cut或其他进程更有效。
(感谢@CharlesDuffy让提示阅读没有无用cat的data,以及while循环。)
https://stackoverflow.com/questions/47164363
复制相似问题