다음과 같이 파일 이름이 숫자 값으로 계속 변경되는 디렉토리가 있습니다.
-rw-rw----. 1 root root 10493952 May 7 10:39 A0000000.LOG
-rw-rw----. 1 root root 10493952 May 7 08:38 A0000001.LOG
-rw-rw----. 1 root root 10493952 May 7 08:38 A0000002.LOG
...
...
-rw-rw----. 1 root root 10493952 May 7 08:38 A0000582.LOG
...
and so on...
이제 언제든지 내 애플리케이션은 나열된 파일에서 파일 이름을 삭제합니다. 나는 버려야 해저것파일 및 다음보다 큰 값을 가진 기타 파일저것파일을 원격 호스트로 재동기화하는 중
애플리케이션이 file 을 던졌다고 가정합니다 A0000096.LOG
. 나 A0000097.LOG
역시 창조되는 것을 본다면::
rsync A* --exclude A0000096.LOG --exclude A0000097.LOG user@remoteHost:/somedir/
지침:
애플리케이션은 매시간 실행되는 rsync cron 작업에 다른 파일 이름을 생성합니다. 이 예에서 파일 이름은 다음과 같습니다.
A0000096.LOG
A0000096.LOG
애플리케이션 출력 파일 이름( 위 예에서) 보다 값이 높은 파일은 애플리케이션 출력 파일 이름과 동일한 생성 날짜/시간 스탬프를 가질 수 있습니다.rsync가 시작되면 애플리케이션의 출력 파일 이름은 더 높은 값을 가진 파일보다 최신 날짜/타임 스탬프를 가질 수 있습니다.
더 높은 값의 파일이 생성되지 않거나, 1개 이상의 파일이 생성될 수 있습니다(아마도 10~20개)
질문:이러한 제한으로 인해 모든 상위 숫자 파일을 rsync bash 스크립트에 공급하여 제외할 수 있는 방법을 알 수 없습니다.
도움을 주시면 감사하겠습니다.
답변1
질문을 올바르게 이해했다면 A0000000
.rsync 범위 내의 모든 파일을 통해 rsync를 원할 것입니다 A0000095
. A*
제외할 파일 이름을 식별하는 것이 아니라 원하는 파일 이름을 생성하기 위해 긍정적인 와일드카드 목록(glob 또는 파일 이름 확장 패턴이라고도 함)을 사용한다고 말하지 마십시오 . 이는 범위를 하위 범위로 나누면 달성됩니다.
Subrange Wildcard
A0000000-A0000089 A00000[0-8][0-9]
A0000090-A0000095 A000009[0-5]
그래서 당신은 말할 것입니다
rsync A00000[0-8][0-9] A000009[0-5] user@remoteHost:/somedir/
한 가지 예에서 이 접근 방식을 일반화할 수 없다면 97169를 고려해 보세요.
Subrange Wildcard
A0000000-A0089999 A00[0-8][0-9][0-9][0-9][0-9]
A0090000-A0096999 A009[0-6][0-9][0-9][0-9]
A0097000-A0097099 A00970[0-9][0-9]
A0097100-A0097159 A00971[0-5][0-9]
A0097160-A0097168 A009716[0-8]
상상할 수 있듯이 이러한 와일드카드 중 일부는 기존 파일과 일치하지 않습니다. 이 경우에는
shopt -s nullglob
rsync
명령을 계속 실행 하고 실패한 와일드카드를 무시하도록(예: null로 확장) 쉘에 지시합니다 .
답변2
숫자는 동일한 너비로 0으로 채워지기 때문에 숫자 순서는 사전식 순서와 동일합니다. 따라서 귀하의 질문은 어휘 순서대로 특정 파일로 시작하는 파일을 삭제하는 것입니다.
줄 바꿈으로 구분된 파일 이름을 포함하는 문자열을 작성하고 문자열 대체를 사용하여 문자열의 끝을 제거한 다음 따옴표가 없는 확장을 사용하여 잘린 문자열을 다시 목록으로 전환함으로써 이를 수행할 수 있습니다. 파일 이름에 개행 문자가 없고 쉘이 bash 또는 ksh라고 가정합니다(일반 sh의 경우 명명된 배열 대신 위치 인수를 사용해야 함).
nl=$'\n' # newline, we use it as a separator
cut_from=A0000096.LOG
log_files=(A???????.LOG)
set -f; IFS="$nl" # disable wildcard expansion and set the word separator to newline only
log_files="$nl${log_files[*]}$nl" # turn the array into a string with newlines separating elements
log_files=(${log_files%"$nl$cut_from$nl"}) # remove elements from $cut_from onwards and split the string into an array
unset IFS; set +f
rsnyc -a "${log_files[@]}" … elsewhere:/some/dir
답변3
내 질문에 대답하려면 다음을 수행하십시오.
방법 1
CUT_LOG=A0000096.LOG #Assuming app throws a file - A0000096.LOG and I've to exclude this and any other files having higher numerical value than this file: A0000096.LOG. e.g. A0000097.LOG etc.
LISTLOG=`ls -1 /Source_Dir/A*.LOG | sed "/$CUT_LOG/,$ d"` # Instantiate a variable - LISTLOG, that will hold files list excluding A0000096.LOG and any other files having higher numerical value than this A0000096.LOG
rsync -a `echo "${LISTLOG[@]}"` user@remoteHost:/somedir/ # Transfers the files excluding A0000096.LOG and excluding any other files with higher numerical values than A0000096.LOG
방법 2【루프 사용(권장하지 않음)
for line in `echo "${LISTLOG[@]}"`; do # Recursively loop through the array and rsync each entry
rsync -a $line user@remoteHost:/somedir/
done
답변4
접선 폐쇄자일스의 관찰파일 이름은 어휘순으로 정렬됩니다. 이를 사용하여 zsh
rsync용 필터 파일을 만들 수 있습니다.
cut_log=A0000096.LOG zsh -c 'logfilter() { ! [[ "$REPLY" < "$cut_log" ]] }; print -l A*.LOG(+logfilter)' > .exclude_file
rsync A* --exclude-from=.exclude_file user@remoteHost:/somedir/
rm .exclude_file
물론 이 모든 것을 zsh에서 기본적으로 수행할 수 있지만 유용한 zsh 기능을 사용하여 bash 스크립트를 확장하는 방법을 보여 드리겠습니다. 이 함수는"글로벌 예선"eString
및 섹션에 설명되어 있습니다 +cmd
. A*.LOG
각 후보를 주어진 함수에 전달하여 필터링을 확장 해야 합니다 . 함수의 인수 이름은 이므로 결과 목록에 포함 또는 제외를 결정하기 위해 REPLY
이를 값과 어휘적으로 비교합니다 .$cut_log
rsync
위의 코드는 로그 파일을 찾고 찾기 위해 로그 파일이 포함된 디렉터리에서 실행된다고 가정합니다 zsh
.
.exclude_file
이렇게 하면 명령을 실행하기 전에 확인하여 연습 실행을 쉽게 수행할 수 있습니다 rsync
.
파일이 너무 많다고 생각되면포함하다명령줄에서(인수가 너무 많으면 명령이 실패하도록) 인수가 부족하면들어오지 못하게 하다파일의 경우 논리를 반전하고 rsync
파일 에 지시한 --include-from
다음 logfilter
논리를 전환하여 반전( !
)을 제거할 수 있습니다.