다른 파일의 구분 읽기로 각 줄을 분할하고 모든 분할 단어 조합을 결과 파일에 저장합니다.

다른 파일의 구분 읽기로 각 줄을 분할하고 모든 분할 단어 조합을 결과 파일에 저장합니다.

names나는 파일의 각 구분 기호로 파일의 각 줄을 분할 delim하고 고유한 단어 화합물을 결과 파일에 저장하고 싶습니다 compounds. names분할되지 않은 줄은 출력 파일에서 제거되어야 합니다. 구분 기호는 4개뿐입니다.-'+

중요한: names파일에 UTF-8로 인코딩된 사람 이름이 포함되어 있습니다.

$ cat delims
 (space is here)
-
'
+
$ cat names
Tania
Günter
Abdel+Aziz
Abdel'Piza
Märie-Pierre

출력 복합 파일은 다음과 같아야 합니다(순서는 중요하지 않음).

Abdel
Aziz
Piza
Märie
Pierre

답변1

필드 구분 기호가 정규 표현식을 확장할 수 있도록 허용하는 awk가 있는 경우 다음과 같은 작업을 수행할 수 있습니다.

$ awk '
    BEGIN{FS=""; while((getline < "delim") > 0){FS = FS=="" ? $0 : FS"|"$0}}
    NF>1 {for(i=1;i<=NF;i++) print $i}
' names
Abdel
Aziz
Abdel
Piza
Märie
Pierre

참고: [ '+-]정규식 대체 대신 문자 집합을 사용하는 것이 더 깔끔합니다 |'|+|-(또한 +리터럴 수량자 또는 정규식 수량자가 사용되는지에 대한 혼동 가능성도 제거합니다). 그러나 -내부적으로 [...]시작이나 끝을 제외한 범위 연산자가 있으므로 항목을 주의 깊게 섞는 것이 필요합니다.

답변2

예제의 4개 문자의 경우 안정적이고 이식 가능하게 작동합니다.

$ cat tst.awk
NR==FNR {
    FS = (NR > 1 ? FS "|" : "") "[" $0 "]"
    next
}
NF > 1 {
    for ( i=1; i<=NF; i++ ) {
        if ( !seen[$i]++ ) {
            print $i
        }
    }
}

.

$ awk -f tst.awk delims names
Abdel
Aziz
Piza
Märie
Pierre

여기에 필요한 복잡성은 4개의 구분 기호 세트에 3개의 메타 문자가 있기 때문입니다.

  1. " "이는 FS에서 "모든 공백 시퀀스"를 의미합니다.
  2. "+"이는 정규식에서 "이전 표현식이 1회 이상 반복됨"을 의미합니다(정규식의 시작 부분에 있거나 뒤에 오는 경우 정의되지 않음 |).
  3. "-"첫 번째 또는 마지막 문자가 아닌 대괄호 표현식 안에 있으면 "범위"를 의미합니다.

따라서 의미가 정의되지 않고 단독으로 사용되는 경우 의미가 문자 그대로가 아니기 때문에 구분 기호의 문자와 같이 |구분된 목록을 만들 수 없으며 모든 항목을 대괄호 표현식으로 묶을 수도 없습니다. 의미는 에서 까지의 문자 시퀀스입니다. , 다시 문자 그대로의 의미가 아닙니다.|-|+|'+<blank>[ -+']-<blank>+

위에서 내가 한 일은 구분 기호에 포함될 수 있는 모든/모든 문자에 대해 작동하는 |대괄호 표현식의 구분된 목록을 만드는 것이었습니다.[ ]|[-]|[+]|[']

답변3

grep, trsort:을 사용하십시오 .

참고: 파일의 위쪽이나 아래쪽으로 -이동 해야 합니다 (그렇지 않으면 범위가 있다고 생각하게 됩니다).delimstr

구분 기호가 포함된 모든 줄을 가져오고 grep모든 구분 기호를 줄 바꿈으로 바꿉니다( delims줄 바꿈 없이 모든 문자 가져오기 사용 tr -d '\n' < delims).

결과를 파이프하여 sort -u중복을 제거하고 출력을 compounds.

grep -F -f delims names | tr -- "$(tr -d '\n' < delims)" '\n' | sort -u > compounds

산출:

$ cat compounds
Abdel
Aziz
Märie
Pierre
Piza

답변4

당신은 또한 수....

awk 'BEGIN{OFS=RS="";FS="\n"; getline;$1=$1;
       s=gsub("-","",$0);FS="["$0((s>0)?"-":"")"]";
       OFS=RS="\n"}
     NF>1{$1=$1; print}' delims names

Abdel
Aziz
Abdel
Piza
Märie
Pierre

여기서 세트를 단일로 읽은 RS다음 다시 조립하여 예상치 못한 공백을 추가하지 않도록 합니다 .FSgetlinedelims$0$1=$1OFS=""

그런 다음 문자 집합의 끝에서만 발생하도록 몇 가지 작은 조정을 수행하여(if 끝에 추가하는 것은 성공적인 합계 gsub임 ) 문자 집합을 .$0--FSgsubs>0[ '+-]FS

이제 RS다시 \n설정할 수 OFS있지만 \n.

그런 다음 모든 곳에서 평소와 같이 비즈니스를 수행 NF>1하지만 OFS="\n"반복할 필요가 없으므로 다음 과 같이 다시 그룹화 NF할 수 있습니다 .$1=$1print

관련 정보