견실 한 경로 구축


16

쉘 스크립트에 여러 변수가 있다고 가정하십시오 (예 : zsh).

FOLDER_1, FOLDER_2, etc.

이 변수는에서 내려 오는 폴더를 나타 /냅니다. 예를 들어 경로가 있다면/home/me/stuff/items

변수는 다음과 같습니다.

FOLDER_1='home'
FOLDER_2='me'
FOLDER_3='stuff'

이제 변수를 연결하여 해당 경로를 다시 만들고 싶다고 가정 해보십시오. 한 가지 가능한 방법은 다음과 같이 경로를 작성하는 것입니다.

PATH=$FOLDER_1/$FOLDER_2/$FOLDER_3/

그러나 일부 변수 FOLDER_i에는 슬래시가 오는 반면 다른 변수 는 알 수 없습니다.

FOLDER_1='home'
FOLDER_2='stuff/'
FOLDER_3='items'

내 질문은 : 어떻게 경로를 강력하게 구축 할 수 있습니까? (예 : 이중 슬래시 방지 및 필요한 곳에 추가).

이 작업을 수행하는 한 가지 방법은 /항상 변수 쌍 사이 에 항상 변수 를 추가하고로 중복 항목을 삭제하는 sed것이지만 작동하도록 할 수는 없습니다 ( /에서 올바르게 처리 하고 있는지 확실하지 않습니다 sed).

또한, 나는 바퀴를 재발 명하고 있습니까? (즉, 이미 내장되어 있습니까?)

마지막으로 변수가 배열 에 있다면 예를 들어 FOLDERS반복 없이이 작업을 수행 할 수 있습니까? (또는 대안으로, FOLDERS배열에 몇 개가 있는지 모르지만 반복 하여).

답변:


12

printf배열과 함께 사용할 수 있습니다 :

parts=("$FOLDER_1" "$FOLDER_2" "$FOLDER_3");
printf '/%s' "${parts[@]%/}"
# Use "printf -v path" to save it into a variable called "path" instead of printing it

이 경우 %연산자는 후행 문자열을 자릅니다 /. 에 적용하면 parts[@]각 배열 구성원을 개별적으로 자릅니다.

printf트릭 을 이해하는 열쇠 는 다음과 man 1 printf같습니다. "포맷 문자열은 인수를 만족시키기 위해 필요한만큼 자주 재사용됩니다."


단일 %방법은 질문에서 언급 한 단일 후행 슬래시에 적용됩니다. 슬래시가 여러 개인 경우에 적합 ${parts[@]%%/*}합니다. 슬래시 문제에 대한 자세한 정보 링크는 다음과 같습니다. UNIX 경로에서 이중 슬래시 란 무엇입니까? 'cd dir / subdir // valid ...
Peter.O

2
@fered : /*이 경우는 수행에 있지 평균 0 개 이상의 슬래시 아니라,하지만를 슬래시는 문자의 수에 따라. 즉, 경로가 슬래시로 시작하면 결과는 빈 문자열이됩니다!
l0b0

예에 따라 슬래시 만있을 것이라고 생각했습니다. 그러나 선행 슬래시의 가능성에 적응하기 위해 bash extglob(정규식 포함)를 사용하면됩니다 .. shopt -s extglob; ${parts[@]%%/+(/)}...
Peter.O

15

간단한 대답은 걱정을 멈추고 여러 개의 슬래시를 사랑하는 것입니다. 다중 슬래시는 단일 슬래시와 동일한 효과를// 갖습니다 (몇 가지 시스템에서 시작하는 경로 가 다른 의미를 제외하고 Windows의 유닉스 에뮬레이션 계층은 내가 지정할 수있는 유일한 것임). 이것은 의도적으로 설계된 것이며 여러 슬래시에 대해 걱정할 필요없이 파일 이름을 어셈블 할 수있는 것이 디자인 결정의 주요 부분이었습니다.

zsh에서 배열 요소를 결합하려면 j 매개 변수 확장 플래그를 사용할 수 있습니다 .

dir=${(j:/:)FOLDERS}

당신이 그것을하는 동안 당신은 중복 슬래시를 뭉개 버릴 수 있지만, 그것은 순전히 미용입니다.

setopt extended_glob
dir=${${(j:/:)FOLDERS}//\/\/##/\/}

ksh 및 bash에서는 $IFS구분 기호로 첫 문자를 사용하여 배열을 결합 할 수 있습니다 . 그런 다음 중복 슬래시를 제거 할 수 있습니다. bash에서는 shopt -s extglob아래 스 니펫의 마지막 줄에서 ksh globs를 활성화 해야 합니다.

IFS=/
dir="${FOLDERS[*]}"
unset IFS
dir=${dir//\/+(\/)//}

3

어떻게 sed작동하지 않습니까? sed 's|/\+|/|g'연결 후 또는 sed 's|/||g'전에 시도하십시오 .


1

bash 4확장 된 글 로빙을 도입하여 매개 변수 대체에서 정규식 일치를 가능하게 ${var....}합니다. 기본적으로 해제되어 있습니다. 스크립트에서 활성화하려면 간단히 쉘 옵션 extglob ...을 설정하십시오 .

$ dir == 라고 가정/home/me/////////stuff//items

shopt -s extglob; dir="${dir//+(\/)//}"

$ dir 의 결과 값

/home/me/stuff/items  

할 일과하지 말아야 할 몇 가지 예가 있습니다 -Bash Extended Globbing

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