이 CSV에서 그룹화 쉼표를 제거하여 변수 수를 2로 변경하고 싶습니다.

이 CSV에서 그룹화 쉼표를 제거하여 변수 수를 2로 변경하고 싶습니다.

처음 몇 행이 다음과 같은 CSV가 있습니다.

c("4288", "57534"),MIB1
c("2272", "2385"),FHIT
c("5550", "10531", "56239"),PREP
c("25809", "23669"),TTLL1

괄호 안에 그룹화된 모든 항목이 하나의 변수가 되도록 변수 수를 조작하고 싶습니다. 불행하게도 내 문서에는 괄호 안에 여러 개의 쉼표로 구분된 값이 있는 3행과 같은 여러 항목이 있습니다.

괄호 안의 쉼표에만 작동하는 sed 표현식이 있나요?

예상되는 출력은 다음과 같습니다.

c("4288" "57534"), MIB1
c("2272" "2385"),FHIT
c("5550" "10531" "56239"),PREP
c("25809" "23669"),TTLL1

건배.

답변1

고급 정규 표현식 perl에는 사용 하지 마세요.sed

perl -pe 's/(?:\G[^,)]*|\([^,)]*)\K,(?=.*?\))//g' input.csv
c("4288" "57534"),MIB1
c("2272" "2385"),FHIT
c("5550" "10531" "56239"),PREP
c("25809" "23669"),TTLL1

이렇게 하면 괄호 안에 나타나는 쉼표가 모두 제거됩니다.

답변2

나는 이미 같은 해결책으로 대답했습니다여기, 이는 귀하의 질문에도 적용되며 여기에서 약간 수정되었습니다.

sed -E ':loop s/(\([^)]*),([^)]*\))/\1\2/; t loop' infile

분해:

노트: 이스케이프되지 않은 문자 클래스 (또는 )외부 문자 클래스는 이스케이프된 문자 [...]클래스와 일치하는 데 사용됩니다. \(합계는 음수 일치입니다.\)[...]()^[^)]임의의 단일 문자이지만)".

그런 다음 우리는 다음을 가집니다:

(\([^)]*): 첫 번째 그룹의 게임은 \1뒤쪽에 있는 심판을 의미합니다.
,: 단일 쉼표와 일치합니다.
([^)]*\)): 두 번째 게임 세트를 소급하여 \2말합니다.

다음과 같은 예제 라인을 고려하고 일치가 어떻게 작동하는지 설명하십시오.

c(("4288", "57534", "somtoher")),d("f1", "f2", "f3"),MIB1

이는 (\([^)]*),([^)]*\))다음과 일치합니다.

  1. 첫 번째 여는 괄호부터 시작하여 (a를 제외한 모든 항목부터 마지막 ​​닫는 괄호까지 ); 따라서 첫 번째 일치 집합은 위 예제 줄의 일부와 일치합니다 .,)\1(("4288", "57534",

  2. 그런 다음 마지막부터 ,첫 번째 닫는 괄호까지의 모든 내용과 )그 자체가 두 번째 일치 항목 집합에 포함되며 위 예제 줄의 일부 \2가 됩니다 ."somtoher")

  3. replacement 섹션에서는 \1\2일치하는 두 그룹을 다시 가져오지만 이들 사이의 쉼표를 제거합니다.

  4. :loop s///; t loop; sed 루프에서 (& 사이의 모든 쉼표(레이블로 사용됨)가 지워질 때까지 1~3단계를 수행합니다.)loop

    첫 번째 시도에서 예제 줄은 다음과 같이 변경됩니다.

    c(("4288", "57534" "somtoher")),d("f1", "f2", "f3"),MIB1
    

    두 번째 시도는 다음과 같습니다.

    c(("4288" "57534" "somtoher")),d("f1", "f2", "f3"),MIB1
    

    세 번째 시도는 다음과 같습니다.

    c(("4288" "57534" "somtoher")),d("f1", "f2" "f3"),MIB1
    

    등.

관련 정보