문자열에서 특정 문자를 제거하려고 합니다. 아이디어는 사용자가 권한과 파일 이름을 입력한 다음 잘못된 권한( 또는 r
가 아닌 권한 )을 제거한다는 것입니다. 내 스크립트는 다음과 같습니다.w
x
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
가 포함되지 않은 첫 번째 명령줄 인수에서 모든 항목을 제거한 다음 실행하는 데 사용됩니다 .r
w
x
chmod
특히 확장된 따옴표에 유의하세요 "$2"
. 이러한 따옴표가 없으면 이름에 공백이나 파일 이름 와일드카드가 포함된 파일에서 스크립트를 사용할 수 없습니다(" 참조).공백이나 기타 특수 문자 때문에 쉘 스크립트가 멈추는 이유는 무엇입니까?").
다음 bash
과 같은 매개변수 대체를 사용할 수 있습니다.
perms=${1//[!rwx]/}
이는 or가 아닌 모든 것을 제거하고 r
결과를 에 할당합니다.w
x
$1
perms
bash
그러면 스크립트는
#!/bin/bash
chmod u+"${1//[!rwx]/}" "$2"
사용하여
shift
chmod u+"$perms" "$@"
여기서 $perms
위의 방법 중 하나로 계산됩니다(앞으로) 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"
이는새로운원래 문자열의 현재 문자가 이러한 문자 중 하나이고 해당 문자가 새 문자열에 없으면(작업에 필요하지 않음) 또는 r
를w
x
chmod
seq
대신 우리는 for
원래 문자열 길이보다 0에서 1만큼 작은 루프를 사용하고, 가독성과 중복 방지를 위해 ch
각 반복에서 현재 문자를 추출합니다.
r
문자에 대해 세 가지 테스트를 수행하는 대신 단일 패턴 일치를 수행하여 문자가 , w
또는 인지 확인합니다 x
.
답변2
${permisos/perm_actual/}
perm_actual
변수 값에서 리터럴 문자열을 제거하세요 ${permisos/$perm_actual/}
. 원하는 것 같습니다.
permisos=${permisos//[^rwx]}
그러나 루프 대신 문자가 rwx
아닌 각 문자를 한 번에 제거하고 [[ $permisos = *[^rwx]* ]]
변수에 문자가 포함되어 있는지 확인할 수 있습니다.
( ${foo//bar}
둘 다 [[ .. ]]
비표준 확장이지만 이미 사용하고 있으므로 Bash/ksh/zsh를 실행 중일 것입니다.)