파일은 다음과 같습니다(모든 공백은 "단일 공백"입니다).
A S1 0 0 0 -9 C C A G C C A G A A
B S2 0 0 0 -9 C C A G C C A G A A
C S3 0 0 0 -9 C C A G C C A G A A
D S4 0 0 0 -9 C C A G C C A G A A
필요한 것은 매 두 번째 열(짝수 필드) 뒤의 공백을 탭( \t
)으로 바꾸는 것입니다. 예상되는 결과는 다음과 같습니다.
A S1"\t"0 0"\t"0 -9"\t"C C"\t"A G"\t"C C
B S2"\t"0 0"\t"0 -9"\t"C C"\t"A G"\t"C C
C S3"\t"0 0"\t"0 -9"\t"C C"\t"A G"\t"C C
D S4"\t"0 0"\t"0 -9"\t"C C"\t"A G"\t"C C
내 원본 파일의 열 수가 더 많았으므로 명령줄은수동적이어서는 안 된다 (특정 수의 필드를 지정합니다).
이 문제에 대해 모든 분들께 묻고 싶습니다.
미리 도움을 주셔서 감사합니다.
답변1
두 개의 공백을 일치시키고 하나는 유지하고 두 번째는 교체하십시오.
sed -E 's/( [^ ]*) /\1\t/g'
답변2
힘 기반 awk
솔루션;) :
awk '{for (i=1;i<=NF;i++) printf("%s%s",$i,i==NF?ORS:((i%2)?" ":"\t"))}' input.txt
그러면 모든 필드를 반복하고 printf
필드 내용 다음에 인쇄하는 방식으로 인쇄합니다.
- 마지막 필드에 도달하면 "출력 레코드 구분 기호"(기본값은 개행)
- 그렇지 않고 필드 번호가 홀수이면 공백,
\t
a 필드 번호가 짝수인 경우
답변3
짧고 어리석은 방법이지만 16개의 열을 다루고 있다는 것을 알고 있다고 가정하면 완전히 합법적입니다.
$ tr ' ' '\n' <file | paste -d ' \t' - - - - - - - - - - - - - - - -
A S1 0 0 0 -9 C C A G C C A G A A
B S2 0 0 0 -9 C C A G C C A G A A
C S3 0 0 0 -9 C C A G C C A G A A
D S4 0 0 0 -9 C C A G C C A G A A
그러면 각 원래 공백 구분 기호가 개행 문자로 대체됩니다. 그런 다음 paste
공백과 탭 구분 기호가 번갈아 나타나는 16개의 열을 생성하는 결과 스트림(한 줄에 하나의 필드)을 읽습니다 .
awk
탭으로 구분된 쌍으로 필드를 인쇄하는 경우 :
$ awk -v OFS='\t' '{ nf = 0; delete a; for (i = 1; i < NF; i += 2) a[++nf]=sprintf("%s %s", $i, $(i+1)); $0 = ""; for (i = 1; i <= nf; ++i) $i = a[i]; print }' file
A S1 0 0 0 -9 C C A G C C A G A A
B S2 0 0 0 -9 C C A G C C A G A A
C S3 0 0 0 -9 C C A G C C A G A A
D S4 0 0 0 -9 C C A G C C A G A A
코드는 공백으로 구분된 필드 쌍을 배열에 임시로 저장합니다 a
. 그러면 해당 배열의 요소가 현재 레코드의 필드를 바꾸는 데 사용됩니다. 새 레코드는 원하는 효과를 얻을 수 있는 탭 문자를 구분 기호로 사용하여 인쇄됩니다.
독립형 awk
코드:
BEGIN { OFS = "\t" }
{
nf = 0; delete a
for (i = 1; i < NF; i += 2)
a[++nf] = sprintf("%s %s", $i, $(i+1))
$0 = ""
for (i = 1; i <= nf; ++i)
$i = a[i]
print
}
답변4
itertools
다음의 모듈을 사용하세요 .파이썬 3표준 라이브러리.
python3 -c 'import sys
from itertools import zip_longest
ifile = sys.argv[1]
fs,rs,ofs = " ","\n","\t"
with open(ifile) as f:
for l in f:
L = l.rstrip(rs).split(fs)
print(*[fs.join(filter(None,t))
for t in zip_longest(L[::2],L[1::2])],sep=ofs)
' your_file.input
Python의 zip 함수는 두 개 이상의 반복자(이 경우 목록)를 병렬화합니다. Python에는 주어진 목록에서 짝수 요소와 홀수 요소를 참조하기 위한 간결한 슬라이싱 표기법 [::2] 및 [1::2]가 있습니다. 여기서 우리는 짝수 n 홀수 목록에서 각각 하나의 요소를 선택하고 공백으로 결합하여 쌍을 형성한 다음 쌍을 연결합니다(일명,튜플Python 용어로) 및 탭.
이 gensub
기능을 사용하세요GNU awk이를 통해 입력 문자열 내에서 특정 일치 번호를 찾을 수 있습니다.
awk '
{
t=$0
for (i=2; i<NF; i++)
t = gensub(FS, "\t", i, t)
print t
}
' your_file.input
sed 유틸리티를 사용하여 먼저 모든 공백을 개행 문자로 변환합니다. 개행 문자는 패턴 공간에 나타나지 않는 것이 보장되며 패턴 공간에 배치되기 전에 잘립니다. 그런 다음 단계별로 개행 문자를 공백으로 변경하고 다음 개행 문자를 탭으로 교대로 변경합니다. 개행 문자가 부족해질 때까지 반복합니다.
sed -e '
y/ /\n/
:a
s/\n/ /
s//\t/
t a
' your_file.input
Perl에서도 마찬가지입니다.
perl -lpe '
s/ /$|--?"\t":$&/eg;
$|-- unless $|--;
' your_file.input
perl -sF'\x20' -lane '
splice @F, $_, 2, "@F[$_,$_+1]" for 0 .. (@F>>1)-1;
print @F;
' -- -,=$'\t' your_file.input
```