일부 출력 보고를 자동화하는 스크립트를 작성하려고 합니다. 로그 파일(현재 및 향후 "표준화" 예정)은 다음 경로 구조에 저장됩니다.
/<root_path>/<process_one_path>/logs/<time_date_stamp>/<specific_log_file>
/<root_path>/<process_two_path>/logs/<different_time_date_stamp>/<specific_log_file>
폴더에서 항상 최신 상태인 타임스탬프를 제외하고 경로의 모든 부분이 알려져 있습니다.
타임스탬프 대신 와일드카드를 사용하려고 하면 다음과 같은 여러 결과가 나타납니다.
> ls /<root_path>/<process_two_path>/logs/* [tab]
20130102-175103
20130118-090859
20130305-213506
최신 항목만 반환하고 싶습니다. Bash에서 이것이 가능합니까?
참고(저는 zsh가 없습니다. 듣기에는 좋지만 직장에서 사용할 수 있을지 의문입니다.)
답변1
다음은 bash 4.2에서 작동합니다.
list=( /<root_path>/<process_two_path>/logs/* )
echo "${list[-1]}"
Bash가 이전 버전인 경우:
list=( /<root_path>/<process_two_path>/logs/* )
echo "${list[${#list[@]}-1]}"
답변2
POSIX적으로:
set -- /<root_path>/<process_two_path>/logs/*
shift "$(($# - 1))"
printf '%s\n' "$1"
당신이 언급한 이후 zsh
:
print -r /<root_path>/<process_two_path>/logs/*([-1])
POSIX 파일 에 숨겨지지 않은 파일이 없으면 /<root_path>/<process_two_path>/logs
리터럴이 출력되고 /<root_path>/<process_two_path>/logs/*
오류 zsh
가 반환되며 쉘 프로세스는 구문 오류인 것처럼 종료됩니다. 넌 언제나 할 수 있어다루다오류always
막힌, 또는 N
(에 대해 nullglob
) 를 사용합니다.글로벌 예선사건을 개인적으로 처리합니다.
1 glob이 외부 명령에 대한 인수에 있는 경우( print
zsh 내장 때문이 아님) 명령을 실행하는 프로세스만 종료되므로 명령을 취소하는 것으로만 나타납니다. 대화형 셸에서는 다른 구문 오류처럼 셸을 종료하는 대신 프롬프트로 돌아갑니다.
답변3
for 루프를 (잘못) 사용할 수 있습니다. 이와 같이:
for filename in <logdir>/*; do :; done; echo "$filename"
이는 루프가 종료된 후에도 루프 변수에 filename
여전히 마지막 값이 포함되어 있기 때문에 작동합니다. 또한 bash는 알파벳 순서로 전역 확장을 수행하기 때문입니다. 읽다배쉬 매뉴얼더 많은 정보를 알고 싶습니다. 따라 다르니 참고해주세요LC_COLLATE.
bash는 여전히 어떤 작업도 수행하지 않고 모든 파일을 반복해야 하므로 이는 가장 효율적이지 않을 수 있습니다. 그러나 합리적인 수의 파일을 처리할 수 있을 만큼 충분히 빨라야 합니다. 더 이상 속도가 충분히 빠르지 않으면 파일 수가 너무 많아지므로 다른 접근 방식을 고려해야 합니다.
가장 오래된 타임스탬프(먼저 정렬)가 있는 파일 이름을 원하는 경우 다음을 수행할 수 있습니다.
for filename in <logdir>/*; do echo "$filename"; break; done
아니면 이거
for filename in <logdir>/*; do break; done; echo "$filename"
이는 본질적으로 동일하지만(첫 번째 파일 이름 인쇄) 코드 및 스타일 기본 설정에 따라 다른 것보다 선호할 수 있습니다.
답변4
ls -tr | tail -1
이 작업을 수행해야 합니다.