탭으로 구분된 열이 포함된 파일이 있습니다 tsv
. 공백으로 구분된 값이 있는 다섯 번째 열을 가져오고 싶습니다. 구분된 공백을 탭 구분으로 변환하고 새 파일로 저장합니다.
시도:
cut -d"\t" -f"4" input.tsv
awk -v OFS="\t" '$1=$1' input.tsv > output.tsv
입력하다:
Composite_Element_REF Gene_Symbol Chromosome Genomic_Coordinate TCGA-KL-8323-01A-21D-2312-05 TCGA-KL-8324-01A-11D-2312-05 TCGA-KL-8325-01A-11D-2312-05
cg00000027 RBL0 14 53468110 0.0545368833399913 0.635089208882213 0.0581022991274144
cg00000028 RBL1 15 53468111 0.0545366588241415 0.635089205024173 0.0581085373336217
cg00000029 RBL2 16 53468112 0.0545366588040571 0.635089205078394 0.0581085373332275
예상 출력:
Composite_Element_REF TCGA-KL-8323-01A-21D-2312-05 TCGA-KL-8324-01A-11D-2312-05 TCGA-KL-8325-01A-11D-2312-05
cg00000027 0.0545368833399913 0.635089208882213 0.0581022991274144
cg00000028 0.0545366588241415 0.635089205024173 0.0581085373336217
cg00000029 0.0545366588040571 0.635089205078394 0.0581085373332275
답변1
원하는 것이 일부 입력 파일에서 첫 번째 및 다섯 번째 탭으로 구분된 필드를 가져온 input.tsv
다음 해당 필드에 포함된 공백을 탭으로 변경하는 것이라면 아래와 같이 cut
및를 사용하여 이 작업을 수행할 수 있습니다.tr
cut -f 1,5 input.tsv | tr ' ' '\t' >output.tsv
먼저 입력에서 첫 번째 및 다섯 번째 필드를 추출한 다음 모든 공백 문자를 탭 문자로 변경하고 출력을 파일에 씁니다. 첫 번째 필드가 변경되지 않은 상태로 유지되어야 하는 경우 필드에 공백이 포함되어 있지 않은 것으로 간주됩니다.
탭이 기본 구분 기호이므로 cut
이 옵션을 사용할 필요가 없습니다 -d
.
또는 다음을 사용하십시오 awk
.
awk 'BEGIN { OFS=FS="\t" }
{
nf = split($5, a, " ")
$0 = $1
for (i = 1; i <= nf; ++i) $(NF+1) = a[i]
print
}' input.tsv >output.tsv
이렇게 하면 탭으로 구분된 다섯 번째 필드가 공백으로 분할된 다음 모든 원래 필드를 첫 번째 필드로 덮어쓰게 됩니다. 결과 레코드를 출력하기 전에 루프의 첫 번째 필드 뒤에 분할 필드를 추가합니다.
Miller( mlr
)를 사용하면 입력을 헤드리스 TSV(헤더를 단순히 데이터로 처리하도록 헤드리스)로 읽고 관심 있는 필드를 잘라낸 다음 각 레코드를 우리가 하는 것처럼 다시 생성하도록 선택할 수 있지만 더 awk
짧습니다.
mlr --tsv -N put '$* = {1:$1, 2:splita($5, " ")}' input.tsv >output.tsv
각 명령의 출력은 다음과 같습니다.
Composite_Element_REF TCGA-KL-8323-01A-21D-2312-05 TCGA-KL-8324-01A-11D-2312-05 TCGA-KL-8325-01A-11D-2312-05
cg00000027 0.0545368833399913 0.635089208882213 0.0581022991274144
cg00000028 0.0545366588241415 0.635089205024173 0.0581085373336217
cg00000029 0.0545366588040571 0.635089205078394 0.0581085373332275
초기 필드에 헤더를 원한다고 가정하고 -05
입력의 두 번째 줄에 있는 별도의 헤더는 오타이므로 헤더 줄의 최종 필드 끝에 추가해야 한다는 점에 유의하세요.
답변2
사용 awk
:
$ awk -F '\t' '{gsub(OFS,FS,$5); print $1 FS $5}' file
답변3
FWIW 실제로 사용@PrapjhotSingh의 솔루션그러나 일반 작동 분야에 대한 유용한 정보를 제공할 수 있는 몇 가지 대안에 대해서는 계속 읽으십시오...
입력에서 표시된 출력을 얻으려면 표시해야 할 것은 다음과 같습니다.
$ awk -v OFS='\t' '{print $1, $5, $6, $7}' file
Composite_Element_REF TCGA-KL-8323-01A-21D-2312-05 TCGA-KL-8324-01A-11D-2312-05 TCGA-KL-8325-01A-11D-2312-05
cg00000027 0.0545368833399913 0.635089208882213 0.0581022991274144
cg00000028 0.0545366588241415 0.635089205024173 0.0581085373336217
cg00000029 0.0545366588040571 0.635089205078394 0.0581085373332275
$1=$1
또는 코드에서 사용하려고 하는 것을 보면 다음과 같이 할 수 있습니다.
$ awk -v OFS='\t' '{$2=$3=$4=""; $0=$0; $1=$1} 1' file
Composite_Element_REF TCGA-KL-8323-01A-21D-2312-05 TCGA-KL-8324-01A-11D-2312-05 TCGA-KL-8325-01A-11D-2312-05
cg00000027 0.0545368833399913 0.635089208882213 0.0581022991274144
cg00000028 0.0545366588241415 0.635089205024173 0.0581085373336217
cg00000029 0.0545366588040571 0.635089205078394 0.0581085373332275
어디:
$2=$3=$4=""
이 필드를 null로 설정하고 필드가 아직 비어 있지만$0
모든 공백과 탭 문자(사용 중인 기본값과 일치)를 단일 탭(사용 중인)으로 대체하여 원본의 공백을 탭으로 변경합니다. , 및 3개의 필드로 나뉩니다.FS
OFS
$5
$5
$6
$7
$0=$0
필드로 다시 분할해도$0
필드 사이의 공백은 변경되지 않으므로 이제 3개 필드는 사라졌지만 원래 필드 사이의$1
여러 탭$5
(Now$2
및 )$3
은$4
여전히 남아 있습니다.$1=$1
$1
자체적으로 설정되어$0
해당 필드에서 다시 재구성되지만 이제 여러 개의 연속 탭(다시FS
우리가 사용하는 기본 옵션과 일치)이 단일 탭(우리가 사용 중인)으로 대체되어OFS
필드로 구분된 4개 탭의 최종 출력이 생성됩니다.
NF
아래에서 이러한 다양한 단계를 볼 수 있습니다. 필드 사이의 간격 변경과 각 줄의 시작 부분에 인쇄된 값의 변경을 확인하세요.
$ awk -v OFS='\t' '{print NF ": " $0}' < <(printf 'a\tb\tc\td\te f g\n')
7: a b c d e f g
$ awk -v OFS='\t' '{$2=$3=$4=""; print NF ": " $0}' < <(printf 'a\tb\tc\td\te f g\n')
7: a e f g
$ awk -v OFS='\t' '{$2=$3=$4=""; $0=$0; print NF ": " $0}' < <(printf 'a\tb\tc\td\te f g\n')
4: a e f g
$ awk -v OFS='\t' '{$2=$3=$4=""; $0=$0; $1=$1; print NF ": " $0}' < <(printf 'a\tb\tc\td\te f g\n')
4: a e f g
또는 GNU awk와 같은 일부 awk에서는 다음 중 하나를 수행할 수 있습니다.
awk -v OFS='\t' '{$2=$5; $3=$6; $4=$7; NF=4} 1' file
awk -v OFS='\t' '{for (i=2; i<=4; i++) $i=$(i+3); NF=i-1} 1' file
3개 필드 의 값을 위로 이동 한 다음 원래 필드 와 후속 필드를 제거하기 위해 4로 $5
설정했지만 설정은 POSIX별로 정의되지 않은 동작이므로 다른 awks는 값을 존중하거나 무시하거나 다른 작업을 수행할 수 있습니다.NF
$5
NF
답변4
사용행복하다(이전 Perl_6)
~$ raku -ne 'put join "\t", .words.[0,4..*];' file
위 내용은 Perl 계열의 프로그래밍 언어인 Raku로 작성된 답변입니다. 여기서는 (@Kusalananda와 동일) 가정합니다."두 번째 줄에 입력된 유일한 문자는 -05
철자 오류이므로 헤더 줄의 마지막 필드 끝에 추가해야 합니다."(출처: @Kusalananda).
즉, 자동 인쇄가 아닌 한 줄씩 플래그를 사용하여 파일을 한 줄씩 읽습니다 -ne
. Raku의 .words
루틴은 주제(입력 라인)를 가져와 $_
여백의 요소로 나눕니다. 대괄호는 [0,4..*]
원하는 0 인덱스 요소를 선택합니다. 이들은 원하는 출력을 제공하는 탭 join
에 다시 결합됩니다 .\t
입력 예:
Composite_Element_REF Gene_Symbol Chromosome Genomic_Coordinate TCGA-KL-8323-01A-21D-2312-05 TCGA-KL-8324-01A-11D-2312-05 TCGA-KL-8325-01A-11D-2312-05
cg00000027 RBL0 14 53468110 0.0545368833399913 0.635089208882213 0.0581022991274144
cg00000028 RBL1 15 53468111 0.0545366588241415 0.635089205024173 0.0581085373336217
cg00000029 RBL2 16 53468112 0.0545366588040571 0.635089205078394 0.0581085373332275
예제 출력:
Composite_Element_REF TCGA-KL-8323-01A-21D-2312-05 TCGA-KL-8324-01A-11D-2312-05 TCGA-KL-8325-01A-11D-2312-05
cg00000027 0.0545368833399913 0.635089208882213 0.0581022991274144
cg00000028 0.0545366588241415 0.635089205024173 0.0581085373336217
cg00000029 0.0545366588040571 0.635089205078394 0.0581085373332275
"짧은" 줄을 처리하는 것은 상당히 쉽습니다. 조건만 추가하면 됩니다.
~$ raku -ne 'put join "\t", .words.[0,4..*] if .words.elems == 7;' file
마지막으로, 2개의 서로 다른 구분 기호가 있는 파일이 있는 경우 개별적으로/연속적으로 관리할 수 있습니다.
~$ raku -ne '.split("\t", 5).[0,4].split(" ").join("\t").put;' file
마지막 두 솔루션은 위와 동일한 "예제 출력"을 제공합니다.