
특정 단어(예: harley)의 가능한 모든 소문자 및 대문자 순열을 인쇄하는 bash 스크립트를 작성하고 싶습니다.
harley
harleY
harlEy
harLey
...
HARLey
HARLEy
HARLEY
내 순진한 해결책은 이 특정 단어에 대해 n번째(n은 len(word)) 중첩 for 루프를 작성하는 것입니다.
#!/bin/bash
for a in {h,H}; do
for b in {a,A}; do
...
done
done
그러나 다른 단어에 대한 스크립트를 다시 코딩해야 합니다.
이를 수행하는 더 좋은 방법이 있습니까?
답변1
약간 더 나은 솔루션:
echo {h,H}{a,A}{r,R}{l,L}{e,E}{y,Y}
완전한 확장성을 위해:
echo harley \
| perl -nle 'print "echo ",
join "",map { "{" . lc . "," .uc ."}" } split //' \
| xargs -I {} bash -c "{}"
한 줄에 한 단어씩만 입력해야 한다면 다음과 같이 하세요.
for w in {h,H}{a,A}{r,R}{l,L}{e,E}{y,Y};do echo $w;done
덕분에mattdm의 코멘트
해당 확장 가능한 버전은 다음과 같습니다.
echo harley \
| perl -nle 'print join "",map { "{" . lc . "," .uc ."}" } split //' \
| xargs -I {} bash -c 'for w in {};do echo $w;done'
재미삼아 "harley"를 다음으로 바꿔보세요."supercalifragilisticexpialidocious"5분이 지났지만 내 컴퓨터는 여전히 이 작업을 처리 중이며 아마도 완료되지 않을 것입니다. :)
답변2
평가 에코 $(에코 "단어" | sed 's/./{\U&,\L&}/g')
sed 's/./{&,&}/g'
Foo
로 변할 것인데{F,F}{o,o}{o,o}
, 그것은 꽤 쓸모가 없을 것입니다. 그러나\U
and를 추가\L
하면 각 문자의 대문자와 소문자를 얻게 됩니다. 즉,{F,f}{O,o}{O,o}
.- 그런 다음
eval
셸에 {엑스,엑스} 중괄호 시퀀스.
답변3
편집 2:이 답변은 잘못되었습니다. 2^n 조합을 생성하지 않습니다.
편집하다:이유는 모르겠지만 이 해결책은정말@Joeseph R의 Perl 솔루션에 비해 빠릅니다. 0.3초 이내에 "Supercalifragilisticexpialidocious"를 실행합니다!
내 균열은 다음과 같습니다.
#!/bin/bash
str=${1^^} # convert to uppercase
len=${#str} # get length of string
for ((perm=0; perm <= len; perm++)); do
for ((i=0; i <= len; i++)); do
lower=${str,,} # convert to lowercase
# Uppercase n-th letter for permutation
if [ $perm -gt 0 ]; then
nth=${lower:perm-1}
lower=$(echo ${lower:0:perm-1}${nth^})
fi
echo -n ${str:0:i} # print orig string from 0 to $i
echo ${lower:i} # print new string from $i to end
done
done | sort -u
실행하기:
$ ./permutations.sh hi
hi
hI
Hi
HI
$ ./permutations.sh harley
harley
harleY
harlEy
harLey
haRley
hArley
Harley
HarleY
HarlEy
HarLey
HaRley
HArley
HArleY
HArlEy
HArLey
HARley
HARleY
HARlEy
HARLey
HARLeY
HARLEy
HARLEY
자유롭게 포크하고 수정하면 최적화될 수 있다고 확신합니다.https://gist.github.com/ryanmjacobs/4c02ad80f833dee0c307
답변4
원하는 형식으로 출력할 수 있는 최선의 답변을 기반으로 몇 가지 간단한 함수를 작성했습니다.
to_lower ()
{
tr '[[:upper:]]' '[[:lower:]]' <<< $@
}
to_upper ()
{
tr '[[:lower:]]' '[[:upper:]]' <<< $@
}
generate_permutations ()
{
local perm="$@";
perl -e '@foo = split(//, $ARGV[0]);foreach my $c (@foo){print "$c $c\n";}' ${perm} | while read l u; do
echo "{$(to_lower ${l}),$(to_upper $u)}";
done | tr -d '\n';
echo
}
사용법/예:
$ generate_permutations foobar
{f,F}{o,O}{o,O}{b,B}{a,A}{r,R}