성공하면 명령 출력을 파이프합니다.

성공하면 명령 출력을 파이프합니다.
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됩니다 .basenamehead -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입니다.

관련 정보