나는 엄청난 양의 단어 모음을 가지고 있습니다. 많은 단어는 끝에 문자 s가 있기 때문에 다릅니다. 목록에 있는 단어가 문자 s로 끝나는 단어 중 하나를 제외하고 목록의 다른 단어와 정확히 동일한 경우 s로 끝나는 중복 단어를 제거하고 싶습니다. 또한 단어의 현재 위치를 유지할 수 있도록 목록을 정렬할 필요 없이 이 작업을 수행하고 싶습니다.
입력 예:
frog
dogs
cats
cat
dog
frogs
catfish
octopus
예제 출력:
frog
cat
dog
catfish
octopus
답변1
awk를 사용하고 파일을 두 번 읽으십시오. 끝에 s가 있는 배열에 모든 변수를 저장합니다. 두 번째 실행에서 각 줄의 배열을 확인하고 해당 줄이 배열에 없으면 인쇄합니다.
awk 'FNR==NR{a[$0 "s"]++;next}!($0 in a)' file.txt file.txt
더 적은 메모리를 사용하려면 다음을 수행할 수도 있습니다.
awk 'FNR==NR{!/s$/ && a[$0 "s"]++;next}!($0 in a)' file.txt file.txt
답변2
이 작업은 다양한 방법으로 수행할 수 있습니다. 예를 들어 가장 간단한 방법은 데이터를 정렬하고 인접한 행을 비교하는 것입니다.
sort foo |awk '{ if ( plural[$1] == "" ) print; plural[$1 "s"] = 1; }'
주어진 입력
frog
dogs
cats
catfish
cat
dog
frogs
산출
cat
catfish
dog
frog
정렬되지 않음:
#!/bin/sh
awk 'BEGIN { count=0; }
{
words[count++] = $1;
plurals[$1 "s"] = $1;
}
END {
for ( n = 0; n < count; ++n) {
if ( plurals[words[n]] == "")
print words[n];
}
}
' <foo
산출:
frog
catfish
cat
dog
답변3
Bash 스크립트를 사용하십시오.
#!/bin/bash
readarray -t mylist
# compare each item on the list with a new list created by appending `s'
# to each item of the original list
for i in "${mylist[@]}"; do
for j in "${mylist[@]/%/s}"; do
[[ "$i" == "$j" ]] && continue 2
done
echo "$i"
done
목록은 표준 입력에서 읽혀집니다. 테스트 실행은 다음과 같습니다.
$ cat file1
frog
dogs
cats
cat
dog
frogs
catfish
$ ./remove-s.sh < file1
frog
cat
dog
catfish
답변4
grep -f
(파일에서 패턴 가져오기) 옵션의 남용:
grep 's$' input | # output: all lines ending with s
sed -e 's/s$//' | # those same entries, minus the s
grep -F -x -f input | # the entries whose plurals appear
sed -e 's/$/s/' | # the plurals to remove
grep -F -x -v -f - input