날짜가 포함된 파일을 저장하기 위해 하위 디렉터리를 만드는 데 도움이 필요합니다. [닫기]

날짜가 포함된 파일을 저장하기 위해 하위 디렉터리를 만드는 데 도움이 필요합니다. [닫기]

이것은 이 포럼의 새로운 내용이지만 RHEL이나 스크립팅에 익숙하지 않습니다. 그런데 이게 좀 마음에 걸리네요. 다음 파일이 있습니다.

2019-05-01-00.34.00.msg 
2019-05-02-00.36.00.msg
2019-06-14-01.38.00.msg

다음과 같은 디렉토리에 저장하고 싶습니다.

/2019/05/01/<Filename>
/2019/05/02/<Filename>
/2019/06/14/<Filename>

또한 디렉토리에 넣을 때 현재 파일 이름을 유지하고 싶습니다. 또한 bash를 사용하여 이 작업을 수행하고 싶습니다.

어떤 아이디어가 있나요?

답변1

이름을 반복하고 이름을 분할한 -다음 mkdir -p존재하지 않는 경우 디렉터리를 만들고 마지막으로 이동할 수 있습니다. 이 같은:

for file in *msg; do 
    IFS="-" read -r year month day rest  <<< "$file"
    dir="$year/$month/$day/" 
    mkdir -p -- "$dir"
    mv -- "$file" "$dir"
done

답변2

이는 Perl 이름 바꾸기 도구(아니요util-linux 패키지의 이름 바꾸기 도구). 예를 들어

설정:

$ touch 2019-05-01-00.34.00.msg 2019-05-02-00.36.00.msg 2019-06-14-01.38.00.msg
$ ls -l
total 2
-rw-r--r-- 1 cas cas 0 Oct 16 20:56 2019-05-01-00.34.00.msg
-rw-r--r-- 1 cas cas 0 Oct 16 20:56 2019-05-02-00.36.00.msg
-rw-r--r-- 1 cas cas 0 Oct 16 20:56 2019-06-14-01.38.00.msg

이름을 바꿔라:

rename  -n '
  use File::Path qw(make_path);

  if (-f $_ && m/^\d{4}-\d{2}-\d{2}-/) {
    my ($y,$m,$d,$f) = split /-/,$_,4;
    make_path("$y/$m/$d");
    $_ = "$y/$m/$d/$f";
  }' *.msg

스크립트는 먼저 비정규 파일( -f) 또는 패턴과 일치하지 않는 파일 이름을 무시합니다 ^YYYY-MM-DD-. 이렇게 하면 정크 입력이 제공되면 원치 않는 디렉터리가 생성되는 것을 방지할 수 있습니다.

파일 이름을 네 가지 요소로 나눕니다. 처음 3개는 파일 이름에 포함된 연월일( $y, $m$d)이고, 네 번째는 파일 이름의 나머지 부분( $f)입니다.

make_path()다음의 기능을 사용합니다 .파일 경로YYYY/YYYY/MM/, 및 에 대한 디렉터리를 반복적으로 생성하기 위한 표준 모듈입니다 ( 명령 의 옵션 YYYY/MM/DD/과 유사 ). Perl 기능을 세 번 실행할 수도 있었지만 .-pmkdirmkdir()File::Path

$_그런 다음 같음을 설정하여 파일 이름을 올바른 디렉터리로 변경(즉, 이동)합니다."$y/$m/$d/$f"

이것이 Perl이 작동하는 방식의 핵심입니다 rename. 당신은 그것을 사용할 수 있습니다어느s/foo/bar/간단한 검색 및 교체 스타일부터 이 답변에 있는 것보다 훨씬 더 복잡한 스크립트에 이르기까지 Perl 코드 . 코드가 변경되면 $_파일 이름이 변경됩니다. 변경되지 않으면 $_이름이 바뀌지 않습니다.

참고: 이 줄은 rename' -n옵션을 사용하므로시운전오직. 실제로 파일 이름을 바꾸려면 파일을 제거 하거나 다음과 같이 자세한 출력으로 -n변경하세요 .-v

2019-05-01-00.34.00.msg renamed as 2019/05/01/00.34.00.msg
2019-05-02-00.36.00.msg renamed as 2019/05/02/00.36.00.msg
2019-06-14-01.38.00.msg renamed as 2019/06/14/01.38.00.msg

그런데, 파일 이름은 위에 표시된 것처럼 명령줄에 제공되거나 스크립트에 파이프될 수 있습니다( 예를 들어 NUL로 구분된 목록을 출력할 수 있는 다른 입력 파일 이름을 허용할 수 있는 옵션이 rename있습니다 ).-0find ... -print0

마지막으로 rename추가하세요 .아니요-faka 옵션을 사용하도록 지시하지 않는 한 기존 파일을 덮어씁니다 --force.

관련 정보