답변:
이 시도:
INPUT_FILE=`ls -rt "$MY_DIR"/FILE.*.xml | head -1 | xargs -r basename`
플래그를 전달 xargs
하면 표준 입력 ( ) 에서 하나 이상의 항목을 읽는 경우 -r
에만 실행 basename
됩니다 head -1
.
head -1
실행되지만 출력을 보거나 캡처하지 않습니다.
또한 사용자에게의 오류 출력이 표시되지 않게하려면 의 stderr 스트림을로 ls
리디렉션 할 수 있습니다 .ls
/dev/null
INPUT_FILE=`ls -rt "$MY_DIR"/FILE.*.xml 2> /dev/null | head -1 | xargs -r basename`
또한 주위에 따옴표를 추가했습니다 $MY_DIR
. 이렇게하면 $MY_DIR
공백이 있으면 명령이 실패하지 않습니다 .
bash와 같은 최신 쉘을 사용하는 경우 $( )
백틱 대신 캡처 쉘을 사용해야합니다 . 변수 스타일 변경도 고려해야합니다. 일반적으로 스크립트에서 모든 대문자 변수 이름을 사용하지 않아야합니다. 이 스타일은 일반적으로 예약 및 환경 변수를 위해 예약되어 있습니다.
input_file=$(ls -rt "$my_dir"/FILE.*.xml 2> /dev/null | head -1 | xargs -r basename)
ls -rt GLOB 2>/dev/null | head -n1 | xargs -r basename
작동합니다.
파이프 라인에서 모든 명령은 차례대로 시작되고 동시에 실행되지 않습니다. 따라서 출력을 어딘가에 저장해야합니다.
if ls_output=$(ls -rtd -- "$MY_DIR"/FILE.*.xml); then
first_file=$(printf '%s\n' "$ls_output" | head -n 1)
first_file_name=$(basename -- "$first_file")
fi
파일 이름에 줄 바꿈 문자가 포함되어 있지 않다고 가정합니다. xargs
빈 문자, 작은 따옴표 및 큰 따옴표 및 백 슬래시와 관련된 문제도 사용 됩니다. 인용 부호가없는 변수는 공백, 탭 및 와일드 카드 문자에 문제가 있음을 의미합니다. 잊어 버리면로 --
시작하는 파일 이름에 문제가있는 것입니다 -
.
zsh
문자에 대한 제한없이 가장 오래된 파일의 기본 이름을 얻으려면 (명령에 대한 제한된 크기의 인수 문제도 피하십시오) :
first_file_name=($MY_DIR/FILE.*.xml(Om[1]:t))
일치하지 않으면 해당 명령이 실패하고 스크립트가 중단됩니다. 당신은 또한 할 수 있습니다 :
first_file_name=($MY_DIR/FILE.*.xml(NOm[1]:t))
이 경우 first_file_name
일치하는 항목이 있으면 배열에 1 개의 요소가 포함되고 그렇지 않으면 0이 포함됩니다. 그런 다음 다음을 수행 할 수 있습니다.
if (($#first_file_name)); then
printf 'Match: %s\n' $first_file_name
else
echo >&2 No match
fi
디렉토리에서 최신 수정 된 파일을 찾으십시오.
latest() {
local file path=${1:-.} ext=${2-} latest
for file in "${path%/}"/*"$ext"; do
[[ $file -nt $latest ]] && latest=$file
done
[[ $latest ]] && printf '%s\n' "$latest"
}
용법: latest [directory/path/ [.extension]]
를 호출하는 대신 basename
매개 변수 확장을 사용하십시오.
in_file=$(latest in/my/dir .xml)
base_fn=${in_file##*/} base_fn=${base_fn%.*}
다음 내용이 포함 된 디렉토리에서 :
foo.xml bar.xml baz.xml newest.xml
base_fn 변수의 내용은 다음과 같습니다. newest
요청 목적을 위해 이것을 올바르게 사용하려면 다음을 수행하십시오.
check_dir=/path/to/check
check_ext=.xml
if in_file=$(latest "$check_dir" "$check_ext"); then
base_fn=${in_file##*/} base_fn=${base_fn%.*}
else
printf '%s\n' "No file found in $check_dir" >&2
fi
편집 : 질문을 검토 한 결과, 해당 ls
명령 이 디렉토리에서 가장 오래된 파일을 찾고 있음을 깨달았습니다 . 이 같은 함수로 변경 될 수있다 oldest
하고있는 [[ $file -ot $oldest ]] && oldest=$file
동일한 효과를 달성하는 대신. 혼란에 대한 사과드립니다.
주목해야 할 것은 인류의 어떤 상황에서도 절대적으로 ls의 결과를 파싱해서는 안된다는 것입니다. 못.
ls
기반 접근 방식 과 달리 심볼릭 링크가있는 경우 심볼릭 링크 대상의 수정 시간이 고려됩니다 ( 동일한 동작을 얻을 수있는 -L
옵션 추가 ls
).
가장 좋은 옵션은 다음과 같습니다.
ls -rf $MY_DIR/FILE.*.xml
if [ $? -eq 0 ]; then
INPUT_FILE=`ls -rt $MY_DIR/FILE.*.xml|head -1|xargs basename `
else
echo "Error!"
fi
파일이 없으면 ls의 리턴 코드는 2이지만 일부 파일이 발견되면 0이됩니다.
ls
실패하지 않습니다.