aaabefhhhhhthkkd
반복되지 않는 문자만 출력으로 추출하고 순서를 유지해야 하는 문자열이 있습니다 .
문자열에는 대문자 또는 소문자를 포함할 수 있습니다.
입력하다:
aaabefhhhhhthkkd
산출:
beftd
위에서 원하는 출력을 얻으려면 이 논리를 어떻게 정의해야 합니까?
이 명령을 사용해 보았지만 부분적으로만 작동했습니다.
echo "aaabefhhhhhthkkd" | sed 's/./&\n/g' | uniq
위 부분 실행 명령의 출력:
a
b
e
f
h
t
h
k
d
테스트할 문자열 예시:
String 1: aaabefhhhhhthkkd -> Output -> beftd
String 2: AAAbefhhhhhThkkD -> Output -> befTD
String 3: AAAbefhMThkkD -> Output -> befMTD
답변1
uniq
인접한 중복 항목에만 작동합니다. 따라서 사용하려면 먼저 입력을 정렬해야 합니다. 예:
fold -w1 | sort | uniq -u | paste -sd ''
fold -w1
귀하와 동일sed 's/./&\n/g'
하지만 불필요한 개행 문자를 추가로 도입하지 않습니다.sort
반복되는 문자를 인접하게 만듭니다.uniq -u
-u
싱글톤만 인쇄하는 것이 중요합니다.paste -sd ''
결과를 다시 한 줄로 연결
정렬로 인해 모든 경우에 원하는 출력 순서를 얻을 수는 없습니다.
$ echo 'AAAbefhMThkkD' | fold -w1 | sort | uniq -u | paste -sd ''
DMTbef
자신만의 솔루션을 출시하고 싶지 않다면 언제든지 Perl을 사용할 수 있습니다 MoreUtils
.
$ echo 'AAAbefhMThkkD' |
perl -MList::MoreUtils=singleton -ne 'print singleton split //'
befMTD
답변2
모든 UNIX 시스템의 모든 쉘에서 awk를 사용하십시오.
$ echo 'aaabefhhhhhthkkd' |
awk '{
lgth = length()
for (pos=1; pos<=lgth; pos++) {
let = substr($0,pos,1)
if ( gsub(let,"&") == 1 ) {
printf "%s%s", let, (pos<lgth ? "" : ORS)
}
}
}'
beftd
답변3
awk '
{
n=split($0, a, "")
for(i=1; i<=n; i++){
if(gsub(a[i], "") == 1){ printf("%s", a[i]) }
}
print ""
}'
n=split($0, a, "")
:a[1]
문자열의 첫 번째 문자가 되고,a[2]
두 번째 등이n
전체 문자 수입니다.for(i=1; i<=n; i++)
: 모든 배열을 반복해 보겠습니다a
.if(gsub(a[i], "") == 1)
:a[i]
문자열의 모든 문자를 삭제합니다. 문자열에서 한 문자만 삭제된 경우,printf("%s", a[i])
이 문자를 인쇄해 보세요.
print ""
모든 줄이 처리된 후 개행을 인쇄합니다. 입력 라인이 하나만 있는 경우 이는 선택 사항입니다.
단일 라인 압축의 예:
$ awk '{n=split($0,a,"");for(i=1;i<=n;i++)if(gsub(a[i],"")==1)printf("%s",a[i])}' <<< AAAbefhMThkkD
befMTD
참고: POSIX는 빈 문자열에 대한 분할을 정의하지 않습니다. 그러나 gawk
(GNU Awk) mawk
및original-awk
모두 필요에 따라 수행되었습니다.
답변4
테마의 변형
echo 'aaabefhhhhhthkkd' |
awk '{while (length()>0) {t=substr($0,1,1); printf (gsub( t ,"")==1)?t:""} print}'
beftd
$0
비어 있을 때까지 첫 번째 문자를 교체하여 사용 ""
하고 교체가 한 번만 발생하면 인쇄합니다.