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.