要将行转换为制表符分隔,很容易
cat input.txt | tr "\n" " "
但我有84046468行的长文件。我希望将其转换为包含1910147行和44个制表符分隔列的文件。第一列是文本字符串,例如chrXX_12345_+
,其他43列是数字字符串。有没有办法进行这种转变?
有NA
存在,所以我猜sed
并代以" \ n"为" \ t"如果前面的字符串是一个数字不起作用。
示例input.txt
chr10_1000103_+
0.932203
0.956522
1
0.972973
1
0.941176
1
0.923077
1
1
0.909091
0.9
1
0.916667
0.8
1
1
0.941176
0.904762
1
1
1
0.979592
0.93617
0.934783
1
0.941176
1
1
0.928571
NA
1
1
1
0.941176
1
0.875
0.972973
1
1
NA
0.823529
0.51366
chr10_1000104_-
0.952381
1
1
0.973684
示例output.txt
chr10_1000103_+ 0.932203 (numbers all tab-delimited)
chr10_1000104_- etc
(sorry alot of numbers to type manually)
答案 0 :(得分:1)
sed '
# use a delimiter
s/^/M/
:Next
# put a counter
s/^/i/
# test counter
/^\(i\)\{44\}/ !{
$ !{
# not 44 line or end of file, add the next line
N
# loop
b Next
}
}
# remove marker and counter
s/^i*M//
# replace new line by tab
s/\n/ /g' YourFile
如果sed上超过255个标签,那么有些限制(所以44可以)
答案 1 :(得分:1)
这是使用4列而不是44列的正确方法:
$ cat file
chr10_1000103_+
0.932203
0.956522
1
chr10_1000104_-
0.952381
1
1
$ awk '{printf "%s%s", $0, (NR%4?"\t":"\n")}' file
chr10_1000103_+ 0.932203 0.956522 1
chr10_1000104_- 0.952381 1 1
只需更改4到44即可获得实际输入。
如果你在输出中看到control-Ms,那是因为它们存在于你的输入中,所以在运行工具之前使用dos2unix或类似的删除它们,或者使用GNU awk你可以设置-v RS='\n\r'
。
在发布问题时,尽可能使其变得清晰,简单和简洁非常重要,以便尽可能多的人有兴趣帮助您。
BTW,cat input.txt | tr "\n" " "
是UUOC,应该是tr "\n" " " < input.txt
答案 2 :(得分:0)
不是最佳解决方案,但应该有效:
line="nonempty"; while [ ! -z "$line" ]; do for i in $(seq 44); do read line; echo -n "$line "; done; echo; done < input.txt
如果文件中有空行,它将终止。对于更永久的解决方案,我会尝试perl。
编辑:
如果您关注效率,请使用awk。
awk '{ printf "%s\t", $1 } NR%44==0{ print "" }' < input.txt
您可能希望使用| sed 's/\t$//'
删除尾随制表符或使awk脚本更复杂。
答案 3 :(得分:0)
这可能适合你(GNU sed):
sed '/^chr/!{H;$!d};x;s/\n/\t/gp;d' file
如果一行不以chr
开头,则将其附加到保留空间,然后将其删除,除非它是最后一行。如果该行确实开始chr
或它是最后一行,则交换到保留空间并按标签替换所有换行并打印出结果。
N.B。在模式空间中,下一行的开头将保持不变,这将成为新的保留空间。