mv를 사용하여 다른 디렉터리로 이동하고 한 번에 이름 바꾸기

mv를 사용하여 다른 디렉터리로 이동하고 한 번에 이름 바꾸기

나는 +100Mb이고 지난 달에 액세스되지 않은 모든 파일을 알고 싶습니다. 그리고 성공적으로 작성했습니다:

find / -size +100M -atime +30

이제 해당 파일을 /big-not-used라는 폴더로 이동하여 이름을 다음과 같이 변경하고 싶습니다. file_nameYYYYMMDD여기서 file_name은 원본 파일 이름이고 YYYYMMDD는 오늘 날짜(연월일)입니다. 예를 film.mkv들어/big-not-used/film.mkv20161031

내 문장은 다음과 같습니다

find / -size +100M -atime +30 -exec mv {} /big-not-used/... \;

그런데 파일 이름에 오늘 날짜를 추가하는 방법을 모르겠습니다. 나는 그 date +%Y-%m-%d결과 2016-10-31가 유용하다는 것을 발견했습니다 . 이제 의심스러운 것은 이 파일의 이름을 얻는 방법입니다. 수행원: https://stackoverflow.com/questions/5456120/how-to-only-get-file-name-with-linux-find

... -exec basename {} \;

아마도?:

find / -size +100M -atime +30 -exec mv {} /big-not-used/$(basename {})$(date +%Y-%m-%d) \;

그러나 basename이 내가 사용할 이름 대신 파일의 전체 경로로 응답하기 때문에 오류가 발생합니다.

${var##/*/}

파일 이름을 얻으려면 문제는 basename {}이전 표현식의 var에 응답을 어떻게 삽입합니까!?입니다.

아마도?

$(${$(basename {})##/*/})

하지만 예상치 못한 '}' 근처에서 구문 오류가 발생했다고 합니다...

답변1

당신은 다음과 가까워지고 있었습니다:

find / -size +100M -atime +30 \
  -exec mv {} /big-not-used/$(basename {})$(date +%Y-%m-%d) \;

$(...)그러나 인용하지 않으면 구문 의 쉘 확장이 발생합니다.find명령이 실행되기 전에. 즉, 실제로 실행되는 위의 명령줄은 다음과 같습니다.

find / -size +100M -atime +30 \
  -exec mv {} /big-not-used/{}2016-10-30 \;

의 결과는 $(basename {})이므로 {}전체 경로 이름으로 끝나는 것입니다. 대신 이것을 시도해 보세요:

find / -size +100M -atime +30 \
  -exec sh -c 'mv {} /tmp/big-not-used/$(basename {})$(date +%Y-%m-%d)' \;

테스트를 위해 다음과 같이 mv로 바꿀 수 있습니다.echo mv

find / -size +100M -atime +30 \
  -exec sh -c 'echo mv {} /tmp/big-not-used/$(basename {})$(date +%Y-%m-%d)' \;

...그리고 생성된 명령이 어떻게 보이는지 확인하세요.

답변2

단 한 번의 호출만 가능하도록 Lark의 솔루션을 약간 개선했습니다 sh.

find / -size +100M -atime +30 -exec sh -c \
  'for f do mv "$f" /tmp/big-not-used/"$(basename "$f")$(date +%Y-%m-%d)"; done' sh {} +

또는 sh전화를 전혀 하지 않고 다음을 수행합니다.

while IFS= read -r f; do
  mv "$f" /tmp/big-not-used/"$(basename "$f")$(date +%Y-%m-%d)"
done < <(find / -size +100M -atime +30)

(나중에는 파일 이름에 개행 문자가 없다는 가정 하에 진행됩니다.)

-v디버깅을 위해 추가 할 수도 있습니다 mv(지원되는 경우).

관련 정보