【问题标题】:Awk: Splitting file on nth occurence of delimiter, wrong first split fileawk:在第 n 次出现分隔符时拆分文件,错误的第一个拆分文件
【发布时间】:2017-02-18 00:26:45
【问题描述】:

我想在每出现一次“>”时拆分一个文本文件,如下面粘贴的(对不起,长度)。例如,每第二次出现“>”,但我需要能够更改该数字。

test_split.txt:

>eeefkdfn
a
a
a
>c 4ufjdhf
b
b
b
b
>
c
c
> c
d
d
d
d
d
>3
>cr
>c3
e
e
e
e
e
> 5
f
f
f
f
>cr
g
g
g
g
> cr dkjfddf
h
h
h
h

所以我想要这些输出文件(只显示前两个):

file_1.txt:

>eeefkdfn
a
a
a
>c 4ufjdhf
b
b
b
b

file_2.txt:

>
c
c
> c
d
d
d
d
d

等等

问题:

我一直在尝试使用这个 awk 命令来实现这个结果:

awk '/^>/ {n++} { file = sprintf("file_%s.txt", int(n/2)); print >> file; }' < test_split.txt

我得到了正确的输出(拆分)文件,而不是所需的结果,除了第一个文件,它只包含一次“>”(而不是两个),如下所示:

cat test_0.txt

>eeefkdfn
a
a
a

cat test_1.txt

>chr1 4ufjdhf
b
b
b
b
>
c
c

知道这是为什么吗?谢谢!

【问题讨论】:

  • 有点难以理解您想要实现什么以及您的问题是什么。我建议您重新表述您的问题,并稍微合并一下,并清楚地突出“问题部分”和“问题部分”,这将使我们所有人更容易理解并尝试帮助您与问题。谢谢。
  • 稍微编辑了我的帖子,希望更清楚!如果不让我知道缺少什么
  • 交换增量和打印部分的顺序。您在第一部分之前递增。
  • @stark 你能举个例子吗?我不确定你的意思
  • 你需要考虑你的数学。首先你做 1/2 这将是零,但是当它再次增加到 2/2 时,你已经在更改文件的名称

标签: bash awk


【解决方案1】:

这似乎更简单:

awk 'BEGIN{i=1}/^>/{cont++}cont==3{i++;cont=1}{print > "file_"i".txt"} file

会给你预期的结果:

$ cat file_1.txt
>eeefkdfn
a
a
a
>c 4ufjdhf
b
b
b
b

$ cat file_2.txt
>
c
c
> c
d
d
d
d
d

说明

BEGIN{i=1}:文件计数器初始化。

/^&gt;/{cont++}:计算找到的每个&gt;

cont==3{i++;cont=1}:增加文件计数器并在&gt; char 再次出现的第三次出现时初始化 cont var。

{print &gt; "file_"i".txt"}:将输出定向到预期的文件。

【讨论】:

  • 输入很大时会留下很多未关闭的文件句柄。
  • @anubhava 未关闭的文件句柄是什么意思(尝试查找但没有找到太多)
  • (我还是个初学者)你能解释一下 cont==3{i++;cont=1} 部分吗?为什么==3?谢谢!
  • 缩短这个awk -vn=2 '/^&gt;/{i++}{print &gt; "file_" (int((i-1)/n)+1) ".txt"}' file
  • @arielle:每次您执行&gt; afile 时,它都会打开一个文件句柄进行写入。如果我们创建大量文件并且不在awk 中关闭这些文件,这就像内存泄漏。这就是我在代码中添加对close(file) 的调用的原因。
【解决方案2】:

您可以使用此 awk 对编号 n 进行动态控制,其中文件将在输入数据中 nth 出现 &gt; 时拆分:

awk -v n=2 'function ofile() {
   if (op)
      close(op)
   op = sprintf("file_%d.txt", ++p)
}
BEGIN {
   ofile()
}
/>/ {
   ++i
}
i > n {
   i=1
   ofile()
}
{
   print $0 > op
}
END {
   close(op)
}' file

如果您想复制/粘贴,这里有一个衬里:

awk -v n=2 'function ofile() {if (op) close(op); op = sprintf("file_%d.txt", ++p)} BEGIN{ofile()} />/{++i} i>n{i=1; ofile()} { print $0 > op }' file

【讨论】:

    猜你喜欢
    • 2013-03-11
    • 1970-01-01
    • 2018-09-29
    • 1970-01-01
    • 1970-01-01
    • 2019-03-19
    • 1970-01-01
    • 1970-01-01
    • 2021-12-08
    相关资源
    最近更新 更多