
Deja Dup을 사용하여 이전 시스템의 일부 백업을 만들었습니다. 현재 배포판에서는 사용할 수 없으므로 방금 데이터를 추출했습니다. 이제 이 데이터를 다시 의미 있게 만들려면 다음과 같이 파일을 분류해야 합니다.
cat ? ?? > file
물론 물음표는 파일 수에 따라 다릅니다.
추출된 데이터 구조는 다음과 같습니다.
some/long/path/to/file/[original_filename_converted_to_folder.extension]/
따라서 파일 이름은 내부에 번호가 매겨진 파일이 있는 폴더입니다(예: 1, 2..20..300.. 등). 파일(현재 폴더)마다 내부에 번호가 매겨진 파일 수가 다릅니다.
그래서 모든 디렉토리를 얻고 싶습니다. 존재하다. 그런 다음 해당 디렉토리에 하위 디렉토리가 없으면 모든 파일을 하나로 묶고 해당 폴더 이름(실제 파일 이름이므로)을 지정하고 한 디렉토리(..)로 전송한 다음 디렉토리를 삭제합니다(디렉토리를 생성하려면 를 사용하십시오). ) 파일 및 파일 이름)
그래서 스크립트를 작성하기 시작했지만 몇 가지 문제에 부딪혔습니다.
directories = "$(find . -type d)"
for i in "$directories"
do
fdir = "$i"
rdir = "$(dirname "$i")";
fname = "$(basename "$i")";
if [[ "$(basename "$i")" == *"."* ]] then
cd "$i"
FILECOUNT="$(find . -type f -maxdepth 1 -printf x | wc -c)"
DIRCOUNT="$(find . -type d -maxdepth 1 -printf x | wc -c)"
DIRCOUNT=$(( DIRCOUNT - 1 ))
if DIRCOUNT == 0 then
if FILECOUNT != 0 then
# >> this is the problematic part
DIGITS = "$(grep -o "[s|S]" <<<"$x" | wc -l)"
cat "$QUESTIONMARKS" > "$fname"
mv "$fname" "$rdir" +"/"+ "$fname"+".restored"
rm *
cd ..
rmdir fname
mv "$fname"+".restored" "$fname"
# << end of problems
fi
fi
fi
done
그래서 질문은 - 디렉토리의 파일 번호를 기반으로 물음표를 생성하는 방법입니다. 디렉토리에 1자리 파일 번호가 있는 경우 명령은 다음과 같아야 합니다.
cat ? > file
디렉토리에 2자리 파일 번호가 있는 경우:
cat ? ?? > file
3인 경우:
cat ? ?? ??? > file
이해했구나..
그 후 계속해야 할 명령 목록을 작성했는데, 이렇게만 추가해야 합니까, 아니면 ()로 묶어야 합니까?
이런 스크립트에서 CD가 괜찮나요? 문제가 생기지 않을까요?
이를 달성하기 위한 다른 가능한 솔루션이 있습니까?
감사해요.
답변1
내가 올바르게 이해했다면 귀하의 디렉터리에는 1
, 2
, 3
등의 파일이 포함되어 있으며(최대 변수 제한까지) 각 디렉터리를 해당 디렉터리와 동일한 이름을 가진 파일로 바꾸려고 하며 해당 파일은 다음 파일의 연결입니다. 숫자 순서.
이 답변에서는다루기 힘든, bash와 다른 도구를 조합하는 것보다 사용하기가 더 쉽기 때문입니다. 이 방법을 sh 및 find로 변환할 수 있습니다(bash 및 GNU 찾기는 일반 sh 및 POSIX 찾기보다 쉽습니다).
첫째, 점의 존재는 디렉토리를 찾는 데 매우 유용한 경험적 방법이 아닌 것 같습니다. 이름에 점이 포함되지 않은 파일을 놓치고 이름에 점이 포함되지 않은 디렉토리를 찾을 것입니다. 숫자로 명명된 파일이 포함된 디렉터리를 찾는 것이 더 안정적으로 보입니다(비록 완벽하지는 않지만 아무것도 아닙니다). 경고: 테스트되지 않은 코드:
#!/bin/zsh
for dir in **/1(:h); do
files=($dir/*(Nn:t))
for ((i=1; i<=$#files; i++)); do
# if the ith file isn't called i, skip this directory
if [[ $files[i] != $i ]]; then files=; break; fi
done
if [[ -z $files ]]; then continue; fi
# The directory contains only numbered files, and they're in sequence.
# Concatenate the files, move the result into place and remove the directory.
tmp=$(TMPDIR=$dir:h mktemp -d)
mv -- $dir $tmp &&
for x in $tmp/$dir:t/$^files; do cat -- $x; done >$tmp/file &&
mv -- $tmp/file $dir &&
rm -r $tmp
done
zsh 기능 설명:
:t
그리고:h
는역사 확장 수정자파일의 디렉토리 부분과 기본 이름을 각각 가져옵니다.*(Nn)
사용글로벌 예선:n
파일 이름을 사전순이 아닌 숫자순으로 정렬하고,N
디렉터리가 비어 있으면 오류 대신 빈 배열을 가져옵니다.- 이것
^
매개변수 확장 수정자in은 배열의 각 요소에$dir/$^files
접두사를 추가합니다 (단지 첫 번째 요소에 추가하는 대신).$dir/
files