다음과 같은 백업 파일이 포함된 디렉터리가 있습니다.
projectA20210901.gz
projectA20210902.gz
projectB20210901.gz
projectB20210902.gz
projectA*
아직 존재하지 않는 경우 모든 파일을 이동하여 하위 디렉터리를 만들고 싶습니다 ../projectA/
projectB*
./projectB/
날짜 이전의 프로젝트 이름은 2021...
다양하며 파일 이름에서 추출해야 하지만 날짜는 항상 있고 항상 202
2021, 2022 등으로 시작합니다. 2029년 이후에 무슨 일이 일어날지 걱정할 필요가 없습니다.
매개변수 확장하위 디렉터리 이름이 될 프로젝트 이름을 추출하는 데 사용할 수 있습니다.
$ string=projectA20211103-23.gz
$ echo ${string%202*}
projectA
현재 디렉토리의 모든 파일에서 실행되도록 이것을 스크립트에 어떻게 넣을 수 있습니까? 폴더와 심볼릭 링크는 무시해야 합니다.
답변1
첫걸음이 좋습니다. find
Bash 셸에서 이를 사용하고 다음과 같이 결과를 파이핑해 보세요 .
$ find . -maxdepth 1 -iname "project?202?????.gz" -print0 | xargs -0 -I {} bash -c '
var="$1";
var1="${var%%202*}";
mkdir -p "$var1";
echo mv "$var" "$var1"' xargs_bash {}
mv ./projectB20210901.gz ./projectB
mv ./projectA20210901.gz ./projectA
mv ./projectB20210902.gz ./projectB
mv ./projectA20210902.gz ./projectA
논평:
- 위의 내용을 한줄에 작성하시면 됩니다.
mv
출력이 실행하려는 명령과 일치한다고 판단되면 수행하려는 이동 행에서 "echo" 명령을 제거하기만 하면 됩니다 .- 나는 간결함을 목표로 하지 않습니다. 나는 가독성을 좋아합니다.
작동 방식:
find
현재 디렉토리를 살펴보고 거기에서 트리 아래로 작업하십시오.-maxdepth 1
검색을 현재 디렉터리로 제한하도록, 즉 트리 아래로 검색하지 않도록 find에 지시합니다.-iname
다음 패턴에 따라 대소문자를 구분하지 않고 파일 이름을 찾습니다.- 파일 이름 패턴은 특수 문자를 사용합니다.
?
모든 문자를 나타내고,*
임의 개수의 문자를 나타냅니다. print0
출력에서는 각 결과의 끝에 표준 개행 문자 대신 \0 널 문자를 배치합니다. 이는 파일 이름에 개행 문자가 포함되는 경우가 있다는 점을 고려한 것입니다.xargs -0
파이프가 출력의 각 파일 이름이 다음 파일 이름과 널 문자로 구분되어 있음을 인식한 후xargs bash -c '...'
find
문자열 조작을 기반으로 필요에 따라 각 출력을 처리하고 , 필요에 따라 하위 디렉터리를 만들고(mkdir -p
), 마지막으로 요청 시 각 파일을 하위 디렉터리로 이동하는 역할을 하는 bash 셸을 생성합니다.
따라서 cmd가 없는 마지막 줄은 다음 echo
과 같습니다.
$ find . -maxdepth 1 -iname "project?202?????.gz" -print0 | xargs -0 -I {} bash -c 'var="$1"; var1="${var%%202*}"; mkdir -p "$var1"; mv "$var" "$var1"' xargs_bash {}
HTH.
답변2
또 다른 방법은 다음과 같습니다.
cd /mybackups
for file in *;
do
if [ -f "$file" ]; then
newdir=${file%202*}
mkdir -p "$newdir"
mv "$file" "${newdir}"
fi
done