텍스트와 숫자의 조합이 포함된 탭으로 구분된 파일이 있습니다. 각 행은 그대로 유지하고 싶지만 다섯 번째 열에는 6자리 숫자만 존재한다면 그대로 유지하고 싶습니다. 예를 들어:
gene1 NM_033629 598G>A P912 syndrome 1, 192315 syndrome 2, 225750 syndrome 3 610448 score AD hom user 123456 Source
gene2 NM_000459 613G>A V115I syndrome 1 600195 score AD rec user 234567 Source
(증후군 #은 예시로 사용되었으며 임의의 텍스트일 수 있으므로 검색하고 삭제할 수 있는 패턴은 아닙니다.)
나는 출력을 다음과 같이 원한다:
gene1 NM_033629 598G>A P912 192315 225750 610448 score AD hom user 123456 Source
gene2 NM_000459 613G>A V115I 600195 score AD rec user 234567 Source
6자리 숫자를 추출하는 방법에는 4가지가 있지만 그럴 수 없습니다.
ㅏ. 원래 행의 숫자를 출력합니다.
b. 편집된 필드가 포함된 전체 줄을 성공적으로 인쇄합니다. 숫자를 추출하는 데 사용하는 옵션은 다음과 같습니다.
cat inputfile | cut -f 5 |grep -P '(? < !\d)\d{6}(?!\d)'
cat inputfile | cut -f 5 |grep -Po '(?< !\d)\d{6}(?!\d)'
cat inputfile | cut -f 5 |grep -o '[[:digit:]]*'
cat inputfile | cut -f 5 |grep -o "[0-9]\{6\}"
열에 cut을 사용하는 것이 올바르지 않다는 것을 알고 있지만 필드 9에도 6자리 숫자가 있으므로 추출이 올바른지 확인하고 싶습니다. 나는 그것을 모두 함께 유지한다고 주장합니다. 어떤 제안이라도 미리 감사드립니다.
답변1
내가 올바르게 이해했다면 다섯 번째 열은 그 안에 있는 6자리 숫자를 모두 공백으로 연결하기를 원할 것입니다.
아마도:
perl -F'\t' -lape '
$F[4] = join " ", grep {length == 6} ($F[4] =~ /\d+/g);
$_ = join "\t", @F' < file
또는 운영자에 대한 부정적인 의견을 재사용하십시오.
perl -F'\t' -lape '
$F[4] = join " ", ($F[4] =~ /(?<!\d)\d{6}(?!\d)/g);
$_ = join "\t", @F' < file
그리고 awk
:
awk -F'\t' -v OFS='\t' '
{
repl = sep = ""
while (match($5, /[0-9]+/)) {
if (RLENGTH == 6) {
repl = repl sep substr($5, RSTART, RLENGTH)
sep = " "
}
$5 = substr($5, RSTART+RLENGTH)
}
$5 = repl
print
}' < file
grep
그 자체로는 작업에 충분하지 않습니다. grep
패턴과 일치하는 선을 인쇄하도록 설계되었습니다. GNU 또는 ast-open과 같은 일부 구현은 일치하는 줄에서 문자열을 추출 grep
할 수 있지만 pcregrep
이는 매우 제한적입니다.
특정 제한 사항에서 작동할 수 있다고 생각되는 유일한 ++ 접근 방식은 다음을 cut
구현하는 것입니다.grep
paste
pcregrep
grep
n='(?:.*?((?1)))?'
paste <(< file cut -f1-4) <(< file cut -f5 |
pcregrep --om-separator=" " -o1 -o2 -o3 -o4 -o5 -o6 -o7 -o8 -o9 \
"((?<!\d)\d{6}(?!\d))$n$n$n$n$n$n$n$n"
) <(< file cut -f6-)
각 입력 줄에는 최소 6개의 필드가 있고 각 필드의 5번째 필드에는 1~9개의 6자리 숫자가 있다고 가정합니다.
답변2
awk '
BEGIN {
FS = "\t";
OFS = "\t";
}
{
cnt = patsplit($5, arr, /[0-9]{6}/);
$5 = arr[1];
for(i = 2; i <= cnt; i++) {
$5 = $5 " " arr[i];
}
print;
}' input.txt
patsplit(s, a [, r [, seps] ])- 분할 문자열 에스배열로ㅏ및 구분자 배열9월정규 표현식에 대해아르 자형, 필드 수를 반환합니다. 요소 값은 r과 일치하는 s의 일부입니다..
입력하다:
gene1 NM_033629 598G>A P912 syndrome 1, 192315 syndrome 2, 225750 syndrome 3 610448 score AD hom user 123456 Source
gene2 NM_000459 613G>A V115I syndrome 1 600195 score AD rec user 234567 Source
산출:
gene1 NM_033629 598G>A P912 192315 225750 610448 score AD hom user 123456 Source
gene2 NM_000459 613G>A V115I 600195 score AD rec user 234567 Source