나는 다음과 같은 것을 가지고 있습니다 :
- 2016-02-10_03-52.log
- 2016-02-10_04-43.log
- 2016-02-10_02-13.log
- ...
- 2016-03-15_07-03.log
- 2016-03-15_09-08.log
기본적으로 패턴은 YYYY-MM-DD_.log입니다.
동일한 패턴으로 시작하는 모든 파일의 tar를 생성하고 싶습니다. 예를 들면 다음과 같습니다.
- 2016-02-10.tar
- ...
- 2016-03-15.tar
문제는 사전에 패턴을 모르고 구조만 알고 있다는 것입니다.
동일한(알 수 없는) 패턴으로 시작하는 파일을 검색하는 방법을 모르겠습니다.
어떤 도움이라도 대단히 감사하겠습니다. 감사해요
아래의 "명목상 동물" 솔루션을 기반으로 합니다.
내보내기 LANG=C LC_ALL=C 찾기 -이름'[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][ 0-9]*' -printf '%f\n' |.$||g'|Sort|UNIQLO|NAME을 읽을 때 실제로 발견되었습니다. -이름 "${NAME}_" -printf '%p\n' | tar -cJf "${NAME}.xz" -T - --no-unquote 완료
답변1
이를 수행하는 것은 매우 간단한 2단계 프로세스입니다.
첫째, find
최종적으로 보관해야 하는 모든 파일의 목록을 생성하는 데 사용됩니다. sed
각각에 대한 아카이브 이름을 생성하는 데 사용됩니다 . sort
출력을 살펴보고 필터링 uniq
하여 원하는 모든 아카이브의 이름이 있는지 확인하십시오. 예를 들어:
find . -name '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]_*' -printf '%f\n' | sed -e 's|_.*$||g' | sort | uniq
위 형식을 사용하여 %f
전체 경로가 아닌 파일 이름만 가져옵니다.
다음으로 작은 bash 루프를 통해 각 아카이브 이름을 읽고 find
이를 다시 사용하여 모든 로그 파일을 찾은 다음 해당 목록을 tar
아카이브로 파이프합니다.
이와 같은 명령을 실행하려면 C/POSIX 로케일을 사용해야 합니다(현지화된 오류 메시지나 기타 형식은 사용하지 않음). 환경 변수를 LANG
로 설정 LC_ALL
하면 됩니다 C
. 그래서 제가 사용하는 전체 명령 순서는 다음과 같습니다.
export LANG=C LC_ALL=C
find . -name '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]_*' -printf '%f\n' | sed -e 's|_.*$||g' | sort | uniq | while read NAME ; do
find . -name "${NAME}_*.log" -printf '%p\n' | tar -cJf "${NAME}.tar.xz" -T - --no-unquote
done
-J
의 매개변수는 -cJf
XZ 압축을 참조합니다(빠르고 좋으며 아마도 정말로 원할 것입니다). 저는 -cJf
"XZ 아카이브 파일 생성"을 읽는 것을 좋아합니다. -T -
이는 각 아카이브의 파일이 표준 입력에서 제공된다는 의미 이며 --no-unquote
파일 이름이 참조 없이 원시임을 의미합니다.
아카이브 이름의 패턴은 여기서 글로빙하는 데 적합합니다. (즉, 에 공급할 수 있습니다 find -name ...
.) 패턴에 *
, 또는 가 ?
포함 되어 있으면 이를 이스케이프해야 합니다. 작동하지만 성가시다. OP가 파일 이름 패턴을 아주 잘 선택한 것 같습니다.[
]
답변2
tar
"추가" 옵션( )이 있다는 점을 고려하면 -r
이를 매우 간단하게 유지할 수 있습니다.
for file in *.log; do tar -rf "${file%%_*}.tar" "$file" ; done
z
이 특정 방법( )을 사용하여 로그를 압축하는 옵션을 포함할 수는 없지만 tar: Cannot update compressed archives
쉽습니다.
물론 필요에 따라 와일드카드 패턴에 견고성을 추가하세요. 이 버전에서는 다음과 같이 가정합니다.모두 .log
파일은 하나 또는 다른 아카이브로 압축되어야 합니다.