-
Notifications
You must be signed in to change notification settings - Fork 37
/
Copy pathare_anagrams.sh
executable file
·180 lines (163 loc) · 4.93 KB
/
are_anagrams.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
#!/usr/bin/env bash
# Script Name: are_anagrams.sh
# Description: Checks if two or more strings are anagrams of each other.
# Supports various options to customize comparison behavior.
# Usage: ./are_anagrams.sh [options] [string1 string2 ...]
# Options:
# -i, --ignore-case Ignore case differences.
# -s, --ignore-spaces Ignore spaces and line breaks.
# -p, --ignore-punctuation Ignore punctuation marks.
# -u, --unicode Handle Unicode characters.
# -f, --file FILE Read strings from a file (one per line).
# --stdin Read strings from standard input.
# -v, --verbose Enable verbose output.
# -h, --help Display this help message.
# Examples:
# ./are_anagrams.sh -i "Listen" "Silent"
# ./are_anagrams.sh -i -s -f strings.txt
# echo -e "Dormitory\nDirty room" | ./are_anagrams.sh -i --stdin
# Exit immediately if a command exits with a non-zero status.
set -e
# Default configurations
IGNORE_CASE=false
IGNORE_SPACES=false
IGNORE_PUNCTUATION=false
HANDLE_UNICODE=false
VERBOSE=false
INPUT_STRINGS=()
READ_FROM_FILE=false
INPUT_FILE=""
READ_FROM_STDIN=false
# Function to display usage information
usage() {
echo "Usage: $0 [options] [string1 string2 ...]
Options:
-i, --ignore-case Ignore case differences.
-s, --ignore-spaces Ignore spaces and line breaks.
-p, --ignore-punctuation Ignore punctuation marks.
-u, --unicode Handle Unicode characters.
-f, --file FILE Read strings from a file (one per line).
--stdin Read strings from standard input.
-v, --verbose Enable verbose output.
-h, --help Display this help message."
}
# Function for verbose logging
log() {
if [[ "$VERBOSE" = true ]]; then
echo "$1"
fi
}
# Parse command-line arguments
ARGS=()
while [[ "$#" -gt 0 ]]; do
case "$1" in
-i|--ignore-case)
IGNORE_CASE=true
shift
;;
-s|--ignore-spaces)
IGNORE_SPACES=true
shift
;;
-p|--ignore-punctuation)
IGNORE_PUNCTUATION=true
shift
;;
-u|--unicode)
HANDLE_UNICODE=true
shift
;;
-f|--file)
READ_FROM_FILE=true
INPUT_FILE="$2"
shift 2
;;
--stdin)
READ_FROM_STDIN=true
shift
;;
-v|--verbose)
VERBOSE=true
shift
;;
-h|--help)
usage
exit 0
;;
-*)
echo "Unknown option: $1"
usage
exit 1
;;
*)
ARGS+=("$1")
shift
;;
esac
done
# Collect input strings
if [[ "$READ_FROM_FILE" = true ]]; then
if [[ ! -f "$INPUT_FILE" ]]; then
echo "Error: File '$INPUT_FILE' not found."
exit 1
fi
while IFS= read -r line; do
INPUT_STRINGS+=("$line")
done < "$INPUT_FILE"
elif [[ "$READ_FROM_STDIN" = true ]]; then
while IFS= read -r line; do
INPUT_STRINGS+=("$line")
done
else
INPUT_STRINGS+=("${ARGS[@]}")
fi
# Check if at least two strings are provided
if [[ ${#INPUT_STRINGS[@]} -lt 2 ]]; then
echo "Error: At least two strings must be provided."
usage
exit 1
fi
# Function to clean and sort a string
sort_string() {
local string="$1"
# Remove spaces if needed
if [[ "$IGNORE_SPACES" = true ]]; then
string=$(echo "$string" | tr -d '[:space:]')
fi
# Remove punctuation if needed
if [[ "$IGNORE_PUNCTUATION" = true ]]; then
string=$(echo "$string" | tr -d '[:punct:]')
fi
# Convert to lower case if needed
if [[ "$IGNORE_CASE" = true ]]; then
if [[ "$HANDLE_UNICODE" = true ]]; then
string=$(echo "$string" | awk '{print tolower($0)}')
else
string=$(echo "$string" | tr '[:upper:]' '[:lower:]')
fi
fi
# Split into characters, sort, and reassemble
if [[ "$HANDLE_UNICODE" = true ]]; then
# For Unicode, use sed and sort with appropriate locale
# Assume locale is set properly
sorted_string=$(echo "$string" | sed 's/./&\n/g' | LC_ALL=C sort | tr -d '\n')
else
# For ASCII, use grep -o .
sorted_string=$(echo "$string" | grep -o . | LC_ALL=C sort | tr -d '\n')
fi
echo "$sorted_string"
}
# Main comparison logic
first_string="${INPUT_STRINGS[0]}"
first_string_sorted=$(sort_string "$first_string")
log "First string sorted: $first_string_sorted"
for ((i=1; i<${#INPUT_STRINGS[@]}; i++)); do
current_string="${INPUT_STRINGS[i]}"
current_string_sorted=$(sort_string "$current_string")
log "Current string sorted: $current_string_sorted"
if [[ "$first_string_sorted" != "$current_string_sorted" ]]; then
echo "The strings are not anagrams."
exit 0
fi
done
echo "The strings are anagrams."