Removing letters from strings is easy to do in one go without iterating over the characters of the string. This could be done with tr
like this:
#!/bin/sh
perms="$( printf '%s' "$1" | tr -c -d 'rwx' )"
chmod u+"$perms" "$2"
This uses tr
to first remove everything from the first command line argument that is not any of the characters r
, w
, or x
, then it performs the chmod
.
Note the quoting of the expansions, especially "$2"
. Without these quotes, you would not be able to use your script on files with spaces or filename globbing characters in their names (see e.g. "Why does my shell script choke on whitespace or other special characters?").
In bash
, you may instead use a parameter substitution like
perms=${1//[!rwx]/}
This removes everything that is not r
, w
or x
from $1
and assigns the result to perms
.
The bash
script then becomes
#!/bin/bash
chmod u+"${1//[!rwx]/}" "$2"
By using
shift
chmod u+"$perms" "$@"
where $perms
is computed in any of the above ways (before the shift
), you could even get your script to perform the change on multiple files at once. The shift
removes the first command line argument form the list and "$@"
will expand to the rest of the arguments, each individually quoted.
If you absolutely need to iterate over the characters of the string (you don't), then you may do so like this:
#!/bin/bash
string="$1"
for (( i = 0; i < ${#string}; ++i )); do
ch="${string:i:1}"
if [[ "$ch" == [rwx] ]] && [[ "$new_string" != *$ch* ]]; then
new_string+=$ch
fi
done
printf 'The new string is "%s"\n' "$new_string"
This builds a new string from the old by adding r
, w
, or x
to it if the current character in the original string is one of those characters, and if the character does not already exist in the new string (not necessary for the operation of chmod
).
Instead of using seq
, we use a for
loop running from zero to one less than the original string's length, and for ease of reading and to not repeat ourselves, we extract the current character into ch
in each iteration.
Instead of three tests on the character, we perform a single pattern match to see whether it's r
, w
or x
.