파일이 디렉토리라면 이동하지 마세요 mv bash

파일이 디렉토리라면 이동하지 마세요 mv bash

나는 내 파일을 정리하는 데 도움이 되는 스크립트를 작성하고 있습니다. 기본적으로 스크립트가 확장자에 따라 파일을 구성하기를 원합니다. 현재 솔루션은 특정 디렉터리의 모든 것을 살펴봅니다. 이름에 점이 있는 폴더가 이동되기 때문에 문제가 됩니다.

if statement디렉토리가 실제 디렉토리인지 확인하는 데 사용할 수 있는 방법이 있는지 궁금합니다 . 실제로 디렉터리인 경우 스크립트는 디렉터리를 이동해서는 안 됩니다.

코드 부분입니다. 저는 for loop파일을 반복하기 위해 a를 사용하고 있습니다. 이는 Windows에 있던 이전 배치 스크립트를 대략적으로 기반으로 하므로 이것이 최선의 접근 방식이 아닐 수도 있습니다. 더 나은 해결책이 있다면 알려주십시오.

#!/bin/bash
for i in *.*; do
  filename=$(basename -- "$i")
  extension="${filename##*.}"
  extension="$extension"files
  mkdir -p "$extension"
  mv "$i" "$extension"
done

답변1

개인적으로 for 디렉토리/파일을 사용하여 각각 파일 형식을 지정할 find수 있으므로 a 및 루프를 사용합니다.while-type d/f

실행할 디렉터리의 "라인"으로:

find . -maxdepth 1 -type f -name "*.*" | while IFS="" read -r line; do filename=$(basename -- "$line"); extension="${filename##.}.files"; mkdir -p "$extension"; mv "$line" "$extension"; done

또는 스크립트에서:

#!/bin/bash
find . -maxdepth 1 -type f -name "*.*" |
while IFS="" read -r line; do
    filename=$(basename -- "$line")
    extension="${filename##.}.files"
    mkdir -p "$extension"
    mv "$line" "$extension"
done

설명하다

find .- 현재 디렉터리에서 파일 및 디렉터리 찾기

-maxdepth 1- 현재 디렉터리만 확인합니다. (2는 다음 레벨 디렉터리도 확인합니다.)

-type f- 파일만 일치

-name *.*- 이름에 "."이 포함된 모든 파일

.files나는 또한 그것이 당신이 원하는 것이라고 생각하기 때문에 확장을 변수 선언으로 변경했습니다 . 현재 스크립트에 있는 것처럼 tmp.txt디렉토리에 있다고 말하고 싶다면 다음과 같이 "."를 제거하면 됩니다.tmp.txtfiles

extension="${filename##.}files"

편집하다:

따라서 @Kusalananda가 지적했듯이 a를 반복하는 것은 find아마도 나쁜 생각일 것입니다. 그럼에도 불구하고 find이 기능을 계속 사용할 수 있습니다. 임시 파일을 사용하여 반복하면 됩니다.

#!/bin/bash
find . -maxdepth 1 -type f -name "*.*" > myTemporaryFile

IFS=$'\n' # in case any filenames have spaces in them

for line in $(cat myTemporaryFile); do
    filename=$(basename -- "$line")
    extension="${filename##.}.files"
    mkdir -p "$extension"
    mv "$line" "$extension"
done

rm myTemporaryFile

답변2

나는 Kusalananda의 의견에서 하나, 다른 하나는 완전히 다른 두 가지 방법을 제안하겠습니다.

먼저, bash(및 기타 쉘)에는 test디렉토리인지 확인하는 간단한 연산자가 있습니다. [ -d something ]다음과 같이 사용할 수 있습니다.

#!/bin/bash
for i in *.*; do
  [ -d "$i" ] && continue
  # ... rest of the script
done

위의 코드는 *.*와일드카드의 각 "파일"을 검사하여 디렉터리인지 확인합니다. 디렉터리인 경우 테스트가 통과되고 루프가 다음 항목(있는 경우)으로 계속됩니다.

또는 광범위한 와일드카드 기능이 있는 zsh를 사용할 수 있습니다. 그 중 하나는 특정 유형의 파일(일반 파일, 디렉터리 등)에 대한 일치 항목을 제한하는 것입니다. 다음과 같이 사용할 수 있습니다.

#!/bin/zsh
for i in *.*(.)
do
  # ... rest of your script
done

의 특수 구문은 (.)다음과 같습니다."글로벌 예선"; 괄호는 한정자임을 나타내고 마침표는 일반 파일을 찾고 있음을 나타냅니다. 결과적으로 for루프는 디렉터리가 아닌 파일만 일치하게 됩니다.

답변3

다음을 사용하여 파일인지 확인할 수 있습니다 -f.if

if [ -f "${i}" ];then
  echo "${i} is a file."
else
  echo "${i} is not a file."
fi

-d디렉터리인지 확인하는 데 사용할 수 있으며 !논리를 뒤집기 위해 접두사를 추가할 수 있습니다. 즉, 변수가 파일이 아닌지 확인합니다.

if [ ! -f "${i}" ];then
  echo "${i} is not a file"
fi

관련 정보