我有一个包含 6 列的 csv 文件。我想使用 Python 或 Bash 编写一个脚本,以便我可以生成一个新文件,可能是 txt 文件,其中每行的前三列保持不变(即第 1、2 和 3 列保持在同一行),但接下来的三列(即第 4、5、6 列)插入到新行中,就在上一行的下方。
我的示例文件如下所示:
Column1 Column2 Column3 Column4 Column5 Column6
chr16 2697996 2697997 chr16 2086192 2086193
chr5 112801382 112801383 chr5 138445682 138445683
chr15 26869333 26869334 chr8 119416385 119416386
我的最终文件应如下所示:
Column1 Column2 Column3
chr16 2697996 2697997
chr16 2086192 2086193
chr5 112801382 112801383
chr5 138445682 138445683
chr15 26869333 26869334
chr8 119416385 119416386
答案1
这里有一种awk
方法:
$ awk 'NR>1{for(i=1;i<=NF;i++){ if((i%4)==0) printf "\n"; printf "%s%s",$i,FS;}printf "\n"} END{printf "\n"}' input.csv
chr16 2697996 2697997
chr16 2086192 2086193
chr5 112801382 112801383
chr5 138445682 138445683
chr15 26869333 26869334
chr8 119416385 119416386
假设文件中存在“列”,则在没有它们的情况下处理文件会更容易,因此是NR>1
部分。之后是一个简单的 for 循环,当列号(部分)的整数除以 4 没有余数时,它会插入一个换行符(i%4) == 0
。这是一个非常常见的技巧,用于处理短计数器或需要在特定间隔发生的数据。换行符是必要的,因为我们printf
直接通过纯字符串而不是整行打印数据。
由于您请求了 python,这里也有一个 python 脚本:
#!/usr/bin/env python3
import sys
with open(sys.argv[1]) as fd:
for index,line in enumerate(fd):
items=line.strip().split()
if index == 0:
print(" ".join(items[:len(items)//2]))
continue
left = items[:len(items)//2]
right = items[len(items)//2:]
print( " ".join(left) )
print( " ".join(right) )
工作原理如下:
$ ./break_columns.py ./input.csv
Column1 Column2 Column3
chr16 2697996 2697997
chr16 2086192 2086193
chr5 112801382 112801383
chr5 138445682 138445683
chr15 26869333 26869334
chr8 119416385 119416386
答案2
您可以使用 Miller (https://github.com/johnkerl/miller) 和一个 bash 脚本。从输入开始
Column1 Column2 Column3 Column4 Column5 Column6
chr16 2697996 2697997 chr16 2086192 2086193
chr5 112801382 112801383 chr5 138445682 138445683
chr15 26869333 26869334 chr8 119416385 119416386
并运行
<input tail -n +2 | mlr --nidx --ifs ' ' --repifs cut -f 1,2,3 >out_01
<input tail -n +2 | mlr --nidx --ifs ' ' --repifs cut -f 4,5,6 >out_02
mlr --nidx --ifs ' ' --repifs cat out_01 out_02 >out
mlr -I --n2c --fs ' ' cat then label Column1,Column2,Column3 out
你将会拥有
Column1 Column2 Column3
chr16 2697996 2697997
chr5 112801382 112801383
chr15 26869333 26869334
chr16 2086192 2086193
chr5 138445682 138445683
chr8 119416385 119416386
如果你想要漂亮的打印输出,请将最后一个命令更改为mlr -I --n2p --fs ' ' cat then label Column1,Column2,Column3 out
Column1 Column2 Column3
chr16 2697996 2697997
chr5 112801382 112801383
chr15 26869333 26869334
chr16 2086192 2086193
chr5 138445682 138445683
chr8 119416385 119416386