여러 파일이 있는 디렉토리가 있습니다 foo
.
.
└── foo
├── a.txt
└── b.txt
동일한 이름의 디렉토리로 이동하고 싶습니다.
.
└── foo
└── foo
├── a.txt
└── b.txt
현재 임시 디렉토리를 생성한 bar
다음 이를 이동 foo
하고 이름을 다음과 같이 bar
변경하고 있습니다 .bar
foo
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
임시 파일이나 디렉터리를 생성하는 데 사용하려는 디렉터리 경로에 환경 변수를 설정하는 기능이 있지만 mktemp
macOS의 유틸리티는 다른 BSD 시스템의 동일한 유틸리티와 약간 다르게 작동하는 것으로 보이며 완전히 다른 위치에 디렉터리를 생성합니다. . 그러나 위의 내용은 macOS에서 유효합니다. 사용하기가 약간 더 쉬우 tmpdir=$(TMPDIR=$PWD mktemp -d)
거나tmpdir=$(TMPDIR=. mktemp -d)
질문macOS에서 기본 임시 디렉터리가 다른 파티션에 있고 해당 foo
디렉터리에 많은 데이터가 포함되어 있는 경우(즉, 속도가 느려집니다)
답변2
macOS에서는 rename
Homebrew 설치 명령(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