glob 패턴에서 정의 된 변수를 사용한 배시 대체


10

아래 예제는 문제를 설명합니다. FILENAME대체를 사용할 때 패턴으로 반향되고 인식 될 때 왜 인쇄가 올바르게 이루어 집니까?

#!/bin/bash

FILEPATH_WITH_GLOB="/home/user/file_*"
FILENAME=$(basename "$FILEPATH_WITH_GLOB")
echo $FILENAME                #file_1234
echo ${FILENAME:1:5}          #ile_*   <---why is this not ile_1

답변:


15
FILEPATH_WITH_GLOB="/home/user/file_*"

이제, FILEPATH_WITH_GLOB포함/home/user/file_*

FILENAME=$(basename "$FILEPATH_WITH_GLOB")

FILENAME포함 file_*합니다.

echo $FILENAME                #file_1234

$FILENAME목록 컨텍스트에서 인용되지 않은 확장은 split + glob 연산자를 거치므로 일치하는 파일 목록으로 확장됩니다. 파일 이름 생성매개 변수 확장 시 수행됩니다 .

echo ${FILENAME:1:5}          #ile_*   <---why is this not ile_1

여전히 목록 컨텍스트에서 인용되지 않은 매개 변수 확장이므로 여전히 split + glob을 겪습니다. 그러나 여기서 ile_*패턴은 파일과 일치하지 않으므로 대신 자체로 확장됩니다.

아마 여기에 원하는 것은 :

shopt -s nullglob # have globs expand to nothing when they don't match
set -- /home/user/file_* # expand that pattern into the list of matching 
                         # files in $1, $2...
for file do  # loop over them
  filename=$(basename -- "$file")
  printf '%s\n' "$filename" "${filename:1:5}"
done

또는 배열에 저장할 수 있습니다.

shopt -s nullglob
files=(/home/user/file_*)

첫 번째 일치에만 관심이 있거나 일치하는 것이 하나 뿐인 경우 해당 파일을로 참조 할 수 있습니다 $files. bash그 보통 성가신 행동을 가지 $files로 확장 ${files[0]}하는 대신 모든 (에서 상속 행동 배열의 요소 ksh에 고정, zsh한 번에 대한 원 행동이 될 것입니다)하지만, 여기.


설명 주셔서 감사합니다. FILEPATH_WITH_GLOB=`echo /home/user/file_*` 설명 후 해결 방법을 수행했습니다 .
TheMeaningfulEngineer 2016 년

@ 앨런, 그 문제를 해결하는 잘못된 방법입니다. 여기서 배열을 사용하고 싶습니다. 내 예제 ($ 1, $ 2 ...) bash와 같은 위치 매개 변수 또는 다음 과 같은 배열 files=(/home/user/file_*)입니다.
Stéphane Chazelas

(모든 대문자 변수는 실제로 환경 변수를 위해 예약 echo되어야하며 임의의 데이터에 사용 해서는 안되며 변수는 목록 컨텍스트에서 인용되지 않은 채로 두어서는 안됩니다).
Stéphane Chazelas
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.