Nhận tất cả các kết hợp có thể có của một từ bằng chữ in hoa / in hoa


14

Tôi muốn viết một tập lệnh bash để in tất cả các hoán vị chữ thường và chữ hoa có thể có của một từ nào đó, ví dụ: harley:

harley
harleY
harlEy
harLey
...
HARLey
HARLEy
HARLEY

Giải pháp ngây thơ của tôi là viết một n-th (n là len (từ)) lồng cho vòng lặp for cho từ cụ thể này:

#!/bin/bash
for a in {h,H}; do
    for b in {a,A}; do
    ...
    done
done

Tuy nhiên, tôi sẽ phải viết lại kịch bản cho một từ khác.

Có cách nào tốt hơn để thực hiện điều này?

Câu trả lời:


18

Một giải pháp tốt hơn một chút:

echo {h,H}{a,A}{r,R}{l,L}{e,E}{y,Y}

Đối với khả năng mở rộng đầy đủ:

echo harley \
| perl -nle 'print "echo ",
                    join "",map { "{" . lc . "," .uc ."}" } split //' \
| xargs -I {} bash -c "{}"

Nếu bạn hoàn toàn phải có một từ trên mỗi dòng, hãy đi với

for w in {h,H}{a,A}{r,R}{l,L}{e,E}{y,Y};do echo $w;done

cảm ơn bình luận của mattdm

Phiên bản có thể mở rộng tương ứng sẽ là:

echo harley \
| perl -nle 'print join "",map { "{" . lc . "," .uc ."}" } split //' \
| xargs -I {} bash -c 'for w in {};do echo $w;done'

Để giải trí, hãy thử thay thế "harley" bằng "supercalifragilisticexpialidocious" Đã 5 phút và máy tính của tôi vẫn đang hoạt động trên cái này và có lẽ sẽ không bao giờ kết thúc :)


1
cho w trong {h, H} {a, A} {r, R} {l, L} {e, E} {y, Y}; làm echo $ w; xong
mattdm

4
Một giải pháp một dòng đơn giản hơn:printf '%s\n' {h,H}{a,A}{r,R}{l,L}{e,E}{y,Y}
John1024

2
@ John1024 Tôi khuyến khích bạn đăng bài đó như một câu trả lời, đó là một tính năng được đánh giá thấp của bash'sprintf
Steeldo

10
tiếng vang eval $ (tiếng vang " từ " | sed 's /./ {\ U &, \ L &} / g')
  • sed 's/./{&,&}/g'sẽ biến Foothành {F,F}{o,o}{o,o}, điều đó sẽ khá vô dụng. Nhưng thêm \U\Lbạn có được chữ hoa và chữ thường của mỗi chữ cái; ví dụ {F,f}{O,o}{O,o}.
  • Sau đó, đó là một vấn đề đơn giản của việc sử dụng evalđể nói với trình bao để mở rộng chuỗi niềng răng { X , x }.

1
Bí quyết đẹp :). Nếu tôi có thể chấp nhận hai câu trả lời, bạn cũng sẽ được chấp nhận! Upvote anyway
polym

5

EDIT 2: Câu trả lời này là sai. Nó không tạo ra 2 ^ n kết hợp như bình thường.

EDIT: Tôi không biết tại sao, nhưng giải pháp này thực sự nhanh so với giải pháp perl của @Joeseph R. Nó chạy "Supercalifragilisticexpialidocious" trong chưa đầy 0,3 giây!

Đây là vết nứt của tôi ở đó:

#!/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

Chạy nó:

$ ./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

Hãy thoải mái rẽ nhánh và sửa đổi nó, tôi chắc chắn rằng nó có thể được tối ưu hóa. https://gist.github.com/ryanmjacobs/4c02ad80f833dee0c307


1
Mã rõ ràng không in tất cả các kết quả. Với harleybạn nên có 64 kết quả, harLEYví dụ ở đâu?
Denis

1
@Denis Yup bạn nói đúng. Mỗi lần nên có 2 ^ n kết quả, trong đó n là số ký tự của chuỗi gốc. Câu trả lời này là sai.
ryanmjacobs

0

Nếu bạn thích sử dụng các công cụ sẵn sàng thay vì mã hóa, bạn có thể sử dụng TextMechanic (công cụ tạo kết hợp / hoán vị) và Unit-Conversion.info


Chính xác thì họ sẽ lấy và sử dụng những công cụ đó như thế nào?
Jeff Schaller

Câu trả lời này có thể được cải thiện rất nhiều bằng cách thêm một vài chi tiết như trang chủ hoặc kho GitHub cho các dự án này và / hoặc nếu chúng có thể được cài đặt từ một gói.
Anthony G - công lý cho Monica
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.