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개의 메타 문자가 있기 때문입니다.
" "
이는 FS에서 "모든 공백 시퀀스"를 의미합니다."+"
이는 정규식에서 "이전 표현식이 1회 이상 반복됨"을 의미합니다(정규식의 시작 부분에 있거나 뒤에 오는 경우 정의되지 않음|
)."-"
첫 번째 또는 마지막 문자가 아닌 대괄호 표현식 안에 있으면 "범위"를 의미합니다.
따라서 의미가 정의되지 않고 단독으로 사용되는 경우 의미가 문자 그대로가 아니기 때문에 구분 기호의 문자와 같이 |
구분된 목록을 만들 수 없으며 모든 항목을 대괄호 표현식으로 묶을 수도 없습니다. 의미는 에서 까지의 문자 시퀀스입니다. , 다시 문자 그대로의 의미가 아닙니다.|-|+|'
+
<blank>
[ -+']
-
<blank>
+
위에서 내가 한 일은 구분 기호에 포함될 수 있는 모든/모든 문자에 대해 작동하는 |
대괄호 표현식의 구분된 목록을 만드는 것이었습니다.[ ]|[-]|[+]|[']
답변3
grep
, tr
및 sort
:을 사용하십시오 .
참고: 파일의 위쪽이나 아래쪽으로 -
이동 해야 합니다 (그렇지 않으면 범위가 있다고 생각하게 됩니다).delims
tr
구분 기호가 포함된 모든 줄을 가져오고 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
다음 다시 조립하여 예상치 못한 공백을 추가하지 않도록 합니다 .FS
getline
delims
$0
$1=$1
OFS=""
그런 다음 문자 집합의 끝에서만 발생하도록 몇 가지 작은 조정을 수행하여(if 끝에 추가하는 것은 성공적인 합계 gsub
임 ) 문자 집합을 .$0
-
-
FS
gsub
s>0
[ '+-]
FS
이제 RS
다시 \n
설정할 수 OFS
있지만 \n
.
그런 다음 모든 곳에서 평소와 같이 비즈니스를 수행 NF>1
하지만 OFS="\n"
반복할 필요가 없으므로 다음 과 같이 다시 그룹화 NF
할 수 있습니다 .$1=$1
print