디렉토리를 같은 이름의 디렉토리로 이동하는 방법은 무엇입니까?

디렉토리를 같은 이름의 디렉토리로 이동하는 방법은 무엇입니까?

여러 파일이 있는 디렉토리가 있습니다 foo.

.
└── foo
    ├── a.txt
    └── b.txt

동일한 이름의 디렉토리로 이동하고 싶습니다.

.
└── foo
    └── foo
        ├── a.txt
        └── b.txt

현재 임시 디렉토리를 생성한 bar다음 이를 이동 foo하고 이름을 다음과 같이 bar변경하고 있습니다 .barfoo

mkdir bar
mv foo bar
mv bar foo

하지만 이것은 약간 번거로운 느낌이 들며 bar아직 사용되지 않는 이름을 선택해야 합니다.

이를 달성하는 더 우아하거나 직접적인 방법이 있습니까? 그게 중요하다면 저는 macOS를 사용하고 있습니다.

답변1

이름이 아직 사용되지 않은 현재 디렉터리에 임시 디렉터리를 안전하게 생성하려면 mktemp -d다음과 같이 사용할 수 있습니다.

tmpdir=$(mktemp -d "$PWD"/tmp.XXXXXXXX)   # using ./tmp.XXXXXXXX would work too

mktemp -d명령은 주어진 경로에 디렉토리를 생성하며, X경로 이름 끝에 -es가 임의의 영숫자 문자로 대체됩니다. 생성된 디렉터리의 경로 이름을 반환하고 해당 값을 1tmpdir 에 저장합니다 .

tmpdir그런 다음 이미 수행한 것과 동일한 프로세스를 수행할 때 해당 변수를 사용하고 bar다음으로 바꿀 수 있습니다 "$tmpdir".

mv foo "$tmpdir"
mv "$tmpdir" foo
unset tmpdir

마지막으로 unset tmpdir변수를 삭제하는 것입니다.


1 일반적으로~해야 한다TMPDIR임시 파일이나 디렉터리를 생성하는 데 사용하려는 디렉터리 경로에 환경 변수를 설정하는 기능이 있지만 mktempmacOS의 유틸리티는 다른 BSD 시스템의 동일한 유틸리티와 약간 다르게 작동하는 것으로 보이며 완전히 다른 위치에 디렉터리를 생성합니다. . 그러나 위의 내용은 macOS에서 유효합니다. 사용하기가 약간 더 쉬우 tmpdir=$(TMPDIR=$PWD mktemp -d)거나tmpdir=$(TMPDIR=. mktemp -d)질문macOS에서 기본 임시 디렉터리가 다른 파티션에 있고 해당 foo디렉터리에 많은 데이터가 포함되어 있는 경우(즉, 속도가 느려집니다)

답변2

macOS에서는 renameHomebrew 설치 명령(Perl 스크립트)을 사용할 수 있습니다.

brew install rename

-p그런 다음 (a la )를 사용 mkdir하여 필요한 디렉터리를 만들고 -A접두사를 추가합니다.

% mkdir -p foo/bar; touch foo/{a,b}.txt foo/bar/c.txt
% rename -p -A foo/ foo/*
% tree foo
foo
└── foo
    ├── a.txt
    ├── b.txt
    └── bar
        └── c.txt

이름을 바꾸지 않고 변경 사항을 표시 하려면 실행하세요 -n(테스트 실행):

% rename -p -A foo/ foo/* -n
'foo/a.txt' would be renamed to 'foo/foo/a.txt'
'foo/b.txt' would be renamed to 'foo/foo/b.txt'
'foo/bar' would be renamed to 'foo/foo/bar'

비트 파일이 있으면 simple에서 *해당 파일을 선택할 수 없습니다. 다른 방법을 사용하세요 rename.

  • Bash에서는 도트 파일을 일치시키는 GLOBIGNORE데 (잘못) 사용합니다.*

    $ GLOBIGNORE=.; rename -p -A foo/ foo/* -n
    'foo/.baz' would be renamed to 'foo/foo/.baz'
    'foo/a.txt' would be renamed to 'foo/foo/a.txt'
    'foo/b.txt' would be renamed to 'foo/foo/b.txt'
    'foo/bar' would be renamed to 'foo/foo/bar'
    
  • find또는 -print0다음과 rename함께 사용됩니다 -0:

    % find foo -mindepth 1 -maxdepth 1 -print0 | rename -0 -p -A foo/ -n
    Reading filenames from STDIN
    Splitting on NUL bytes
    'foo/b.txt' would be renamed to 'foo/foo/b.txt'
    'foo/a.txt' would be renamed to 'foo/foo/a.txt'
    'foo/bar' would be renamed to 'foo/foo/bar'
    'foo/.baz' would be renamed to 'foo/foo/.baz'
    

답변3

콘텐츠가 최대 매개변수 제한을 초과할 만큼 충분하지 않은 한(그리고 "허용 가능한" 오류 메시지에 신경 쓰지 않는 한) 다음보다 더 복잡할 필요는 없습니다.

mkdir foo/foo
mv foo/* foo/foo

숨겨진 파일 처리에 대한 수정 사항:

mkdir foo/foo
mv foo/{.,}* foo/foo

답변4

당신은 이미 그것을 알고 있습니다. 현재 날짜/시간(나노초 단위) 및 PID를 복합 접미사로 포함하는 대상 이름과 같이 임시 디렉터리에 대해 다른 이름을 선택할 수 있지만 여전히 디렉터리가 아직 존재하지 않는다고 가정합니다.

dir=foo                         # The directory we want to nest
now=$(date +'%s_%N')            # Seconds and nanoseconds
mkdir "$dir.$now.$$"            # Create a transient directory
mv -f "$dir" "$dir.$now.$$/"    # Move our directory inside transient directory
mv -f "$dir.$now.$$" "$dir"     # Rename the transient directory to the name with which we started

보장된 강력한 솔루션을 원한다면 mkdir성공할 때까지 반복하겠습니다.

now=$(date +'%s_%N')
while ! mkdir -m700 "$dir.$now.$$" 2>/dev/null
do
    sleep 0.$$
    now=$(date +'%s_%N')
done

관련 정보