각 매개 변수에서 후행 슬래시를 제거하는 가장 간단한 방법은 무엇입니까?


99

'$ @'배열의 각 매개 변수에서 후행 슬래시를 제거하여 rsync이름별로 디렉토리 를 복사 하는 가장 간단한 방법은 무엇입니까 ?

rsync -a --exclude='*~' "$@" "$dir"

설명을 위해 제목이 변경되었습니다. 여러 후행 슬래시에 대한 설명과 답변을 이해하려면 편집 내역을 참조하십시오.


답변:


160

여기${parameter%word} 에 자세히 설명 된 확장을 사용할 수 있습니다 . 다음은 동작을 보여주는 간단한 테스트 스크립트입니다.

#!/bin/bash

# Call this as:
#   ./test.sh one/ two/ three/ 
#
# Output:
#  one two three

echo ${@%/}

35
+1 : 매우 현명하게하려면 모든 후행 슬래시가 아닌 단일 슬래시를 제거합니다. 후행 슬래시를 제거하려면 :shopt -s extglob; echo "${@%%+(/)}"
glenn jackman

24
경고 : 모든 경우에 후행 슬래시를 제거하지 않을 수 있습니다. "/"가 인수로 제공되면 후행 슬래시를 제거하면 ... 불행한 결과가 발생합니다.
Gordon Davisson 2012 년

13
PROTIP : tr -s /반복되는 슬래시를 제거한 다음 후행 슬래시를 제거하려면 정규식 변수와 결합 하십시오. 예DIR=$(echo //some///badly/written///dir////// | tr -s /); DIR=${DIR%/}
Dave

1
정말? 떠들썩한 프롬프트 실행에서 set -- one///// two// three four/; shopt -s extglob; echo "${@%%+(/)}"그리고 당신이 무엇을보고 말해
글렌 잭맨

1
@twalberg 코멘트 스레드에서 OP의 질문에 대한 대안적인 답변이 아닌 "protips"에 감사드립니다.
Kyle Strand

39

허용되는 대답은 후행 슬래시 하나를 자릅니다.

여러 후행 슬래시를 자르는 한 가지 방법은 다음과 같습니다.

VALUE=/looks/like/a/path///

TRIMMED=$(echo $VALUE | sed 's:/*$::')

echo $VALUE $TRIMMED

출력되는 내용 :

/looks/like/a/path/// /looks/like/a/path

1
경우에, 당신의 변수를 인용하는 것을 잊지 마세요 그들은 공백을 포함 : TRIMMED=$(echo "$VALUE" | sed 's:/*$::')
tetsujin

1
실제로 그것은 $()구조 내에서 필요하지 않습니다 . 그러나 그것은 또한 무해합니다 :) 따라서 큰 따옴표를 사용 "$VALUE"하지 않을시기와시기를 결정할 필요가 없도록 큰 따옴표를 사용하는 것이 좋습니다 .
Chris Johnson

이것을 이전 캡처와 결합하는 방법이 있습니까? URL에서 프로토콜과 후행 슬래시를 제거하고 싶지만 echo "https://www.example.com/foo/" | sed -e 's|https*://\(.*\)/*$|\1|'작동하지 않습니다 (캡처 그룹이 후행 슬래시와 일치하기 때문에). 두 가지 명령 echo "https://www.example.com/foo/" | sed -e 's|https*://\(.*\)$|\1|' -e 's|/*$||'으로 수행 할 수 있습니다 . 그러나 하나로 수행 할 수 있는지 궁금하십니까?
Adam

이 답변은 매우 큰 입력 파일로 더 잘 작동했습니다. 간단한은 sed 's:/*$::' < in.txt > out.txt초 단위로 작업을 수행
MitchellK

22

이것은 나를 위해 작동합니다. ${VAR%%+(/)}

여기에 설명 된대로 http://wiki.bash-hackers.org/syntax/pattern

쉘 옵션 extglob을 설정해야 할 수 있습니다. 활성화 된 것을 볼 수 없지만 여전히 작동합니다.


2
설정을 조회하려면 : shopt extglob옵션없이
글렌 잭맨

이것은 확장 패턴 언어이며 설정 해야 합니다 extglob.
ingyhere

1
이것은 Mac OS X의 내장 bash에서는 작동하지 않습니다. 위의 Sean Bright의 솔루션은 다음을 수행합니다.${VAR%/}
Alec Jacobson

14

realpath주어진 경로를 해결합니다. 무엇보다도 후행 슬래시도 제거합니다. -s다음 simlinks를 방지하기 위해 사용

DIR=/tmp/a///
echo $(realpath -s $DIR)
# output: /tmp/a

1
존재하는 마지막 노드를 제외하고 경로의 모든 노드가 필요합니다. 사용자가 존재하지 않는 경로를 던지면 realpath실패합니다.
Livy

2
@Livy realpath --canonicalize-missing는 경로의 존재하지 않는 부분에서 절대적으로 올바르게 작동합니다
maoizm

일부 플랫폼에서 realpath가 누락되었습니다
Mark Ribau

8

참고 .bash_profile로 SO에서 찾은 답변을 기반 으로이 두 가지 기능을 추가했습니다 . Chris Johnson이 말했듯이 모든 답변 ${x%/}은 하나의 슬래시 만 제거합니다. 이러한 기능은 그들이 말하는 것을 수행 할 것이며 이것이 유용하기를 바랍니다.

rem_trailing_slash() {
    echo "$1" | sed 's/\/*$//g'
}

force_trailing_slash() {
    echo "$(rem_trailing_slash "$1")/"
}

4

zsh 에서는 :a수정자를 사용할 수 있습니다 .

export DIRECTORY='/some//path/name//'

echo "${DIRECTORY:a}"

=> /some/path/name

이것은 realpath파일 / 디렉토리가 누락 된 것처럼 작동 하지만 실패하지 않습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.