
INPUT_FILE=`ls -rt $MY_DIR/FILE.*.xml | head -1 | xargs basename`
head -1
첫 번째 명령이 성공한 경우에만 두 번째 command()를 실행하고 싶습니다 . 이 명령을 어떻게 개선할 수 있나요?
답변1
이 시도:
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)
답변2
파이프라인에서는 모든 명령이 차례로 시작되고 실행되는 것이 아니라 동시에 시작되고 실행됩니다. 따라서 출력을 어딘가에 저장해야 합니다.
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
답변3
디렉토리에서 최근 수정된 파일을 찾으십시오.
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의 출력을 절대로 구문 분석해서는 안 된다는 것입니다. 안 돼요.
답변4
여기서 가장 좋은 선택은 다음과 같습니다.
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입니다.