다음과 같은 파일이 있습니다.
RSID1 RSID2
chr1_169894240_G_T_b38 chr1_169894240_G_T_b38
chr1_169894240_G_T_b38 chr1_169891332_G_A_b38
chr1_169891332_G_A_b38 chr1_169891332_G_A_b38
chr1_169661963_G_A_b38 chr1_169661963_G_A_b38
chr1_169661963_G_A_b38 chr1_169697456_A_T_b38
chr1_169697456_A_T_b38 chr1_169697456_A_T_b38
chr1_27636786_T_C_b38 chr1_27636786_T_C_b38
chr1_196651787_C_T_b38 chr1_196651787_C_T_b38
chr6_143501715_T_C_b38 chr6_143501715_T_C_b38
다음과 같은 정보를 추출하고 싶습니다 chr1_169894240 chr1_169894240
. 나는 다른 것을 알고 싶지 않습니다. chr_pos
길이가 다르기 때문에 이 정보를 추출하는 방법이 혼란스럽 습니다 . 한 경우에는 길이가 9이고 다른 경우에는 길이가 10입니다. 따라서 cut
특정 값을 표시하기 위해 명령을 사용하면 작성된 값이 표시되지만 chr_pos
일부 값은 표시되지 않습니다. chr_pos_
누구든지 이 문제를 해결하도록 도와줄 수 있습니까?
답변1
awk를 사용하세요:
awk 'NR >1 {split($1, array, "_"); print array[1] "_" array[2]; split($2, array, "_"); print array[1] "_" array[2]}' FILE
답변2
GNU가 있는 경우 grep
아래와 같이 한 줄에 하나씩 일치하는 패턴을 선택할 수 있습니다.
grep -oE '\<chr[[:digit:]]+_[[:digit:]]+' file
정규 표현식은 다음과 같이 나눌 수 있습니다.
\<
- 단어의 시작 부분 일치chr
- 텍스트 문자[[:digit:]]+
- 하나 이상의+
숫자 ( )_
- 텍스트 밑줄
답변3
필요한 필드를 선택하려면 cut
뱅크와 구분 기호를 사용해야 하고 단일 문자 구분 기호만 지원되기 때문에 여기서는 실제로 사용할 수 없습니다 ._
cut
대신 사용하십시오 awk
:
awk -F '[[:blank:]_]+' 'NR > 1 { $0 = sprintf("%s_%d %s_%d", $1, $2, $6, $7) }; 1' file
이는 입력을 공백이나 밑줄로 구분된 필드가 포함된 줄로 처리합니다. 첫 번째 행의 제목은 변경되지 않고 그대로 유지되지만 다른 행은 1번째, 2번째, 6번째, 7번째 공백 또는 밑줄로 구분된 필드를 사용하여 다시 작성됩니다.
너할 수 있다를 사용하세요 cut
. 하지만 약간 지저분해지며 헤더가 손실됩니다.
tail -n +2 file | tr -s '[:blank:]_' '[\t*]' | cut -f 1,2,6,7 | tr '\t' '\n' | paste -d '_ ' - - - -
이는 입력의 첫 번째 줄을 제거한 tail
다음 모든 공백과 밑줄을 탭으로 변환하고(결과에서 연속 탭 제거) 원하는 열을 잘라내고 열을 두 번째 행이 있는 별도의 열로 변환한 tr
다음 paste
재구성된 데이터를 사용합니다. 결과를 마무리합니다.