文字列を繰り返して文字を削除します。

文字列を繰り返して文字を削除します。

文字列から特定の文字を削除しようとしています。アイデアは、ユーザーが権限とファイル名を入力してから無効な権限(またはr非権限)を削除することです。私のスクリプトは次のとおりです。wx

permisos=$1  
for i in `seq 1  ${#1}`; do  
        perm_actual=${1:i-1:1}  
        [[ $perm_actual != *"r"* ]] && [[ $perm_actual != *"w"* ]] && [[ $perm_actual != *"x"* ]] && echo "El permiso $perm_actual es incorrecto, ignorándolo..."  
        permisos=${permisos/perm_actual/}  
done  

chmod u+$permisos $2 

変数から無効な権限が削除されない理由を知っている人はいますかpermisos

事前にありがとう

ベストアンサー1

文字列から文字を削除することは、文字列内の文字を繰り返すことなく一度に簡単に実行できます。これはtr次のように行うことができます。

#!/bin/sh

perms="$( printf '%s' "$1" | tr -c -d 'rwx' )"

chmod u+"$perms" "$2"

これは、最初に文字trが含まれていない最初のコマンドライン引数からすべてのエントリを削除してから実行するために使用されます。rwxchmod

特に拡張引用符に注意してください"$2"。これらの引用符がないと、名前にスペースまたはファイル名のワイルドカードを含むファイルでスクリプトを使用することはできません(「参照」)。スペースやその他の特殊文字が原因でシェルスクリプトが停止するのはなぜですか?")。

bashのパラメータ置換を使用できます。

perms=${1//[!rwx]/}

これはor以外のすべてを削除し、r結果をに割り当てます。wx$1perms

bashその後、スクリプトは

#!/bin/bash
chmod u+"${1//[!rwx]/}" "$2"

使用して

shift
chmod u+"$perms" "$@"

ここでは$perms上記の方法の1つとして計算されます(今後shiftスクリプトに複数のファイルを同時に変更させることもできます。shiftリストから最初のコマンドライン引数を削除し、"$@"それぞれ個別に引用した残りの引数に展開します。


もしあなたなら必須(不要な)文字列の文字を繰り返すには、次のようにします。

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

これは新しい元の文字列の現在の文字がこれらの文字の1つで、その文字が新しい文字列にない場合(作業には不要)、rまたはwxchmod

seq代わりに、for元の文字列の長さよりも0から1だけ小さいループを使用し、読みやすさと重複を防ぐために、各反復chから現在の文字を抽出します。

r文字に対して3つのテストを実行するのではなく、単一のパターンマッチングを実行して文字が、またはであることを確認wしますx

おすすめ記事