저는 bash를 처음 접했습니다. 다음을 수행해야 하는 요구 사항이 있습니다.
- 디렉터리 A와 디렉터리 B에서 동일한 이름을 가진 폴더를 탐색합니다.
- 같은 이름을 가진 두 개의 파일을 찾아 비교합니다(저는diff <(파일 1) <(파일 2 정렬)파일 비교)
- 차이가 없으면 A 디렉토리의 파일을 삭제하십시오.
- 차이가 있는 경우 다음 일치하는 파일 쌍을 무시하고 처리합니다.
- 각 디렉터리의 다음 폴더를 확인하고 일치하는 폴더가 모두 확인될 때까지 프로세스를 반복합니다.
예를 들어, AI 디렉터리에서 폴더 A에는 2개의 파일(파일 1과 파일 2)이 있습니다. 디렉터리 BI에서 폴더 A에는 3개의 파일(파일 1, 파일 2, 파일 3)이 있습니다.
- File1은 두 디렉터리 모두에서 동일합니다. 디렉터리 A에서 제거되었습니다.
- file2에는 차이점이 있습니다. 두 디렉토리 모두에 남아 있습니다.
- file3은 아무 작업도 수행하지 않습니다. - 디렉터리 B에 남아 있습니다.
제가 사용하는 파일은 xml 파일입니다. 파일의 태그 순서는 때때로 다를 수 있지만 파일을 유지하려는 항목이 추가되지 않는 한 내용은 정확히 동일합니다. 태그의 순서가 다른지 여부는 중요하지 않으며 모든 것이 동일하거나 다른지 확인하고 싶습니다. 더 명확하게 제공되기를 바랍니다.
어떤 도움이라도 대단히 감사하겠습니다.
고쳐 쓰다:
그래서 이 작업을 수행했지만 스크립트를 실행할 때 콘솔의 출력은 비어 있습니다. 찾은 것과 동일한 파일을 나열하고 삭제해야 합니다. 어디가 잘못되었나요?
declare -a my_array
shopt -s globstar
cd /mnt/c/filediff/validation/applications/
for file in **; do
if [ -d "$file" ]; then
echo "$file is a directory, skipping.";
else
fileName=${file#*/}
if [[ -e /mnt/c/filediff/package/"$fileName" ]]; then
echo diff -q <(sort "$file") <(sort /mnt/c/filediff/package/"$fileName") &&
my_array=("${my_array[@]}" "$fileName")
#rm /mnt/c/filediff/package/"$fileName"
fi
fi
done
echo -e '\nRemoved the following files -----------------------------------'
for item in "${my_array[@]}"
do
echo "ITEM: *** $item ***"
done
답변1
다음을 수행할 수 있습니다.
for file in /path/to/dirA/*; do
fileName=${file##*/}
diff -q <(sort "$file") <(sort /path/to/dirB/"$fileName") &&
rm /path/to/dirB/"$fileName"
done
이는 파일의 모든 파일을 반복하여 dirA
각 파일을 로 저장합니다 $file
. $file
경로가 포함되므로 파일 이름을 가져와야 합니다. 마지막 슬래시 /path/to/dirA/file1
( ) 모든 콘텐츠를 달성하기 전에. 그런 다음 해당 파일을 디렉터리 B에 있는 동일한 이름의 파일과 자동으로 비교하고, 동일한 경우 성공적으로 종료되면 디렉터리 B에서 파일을 삭제합니다. 이는 "이 명령이 성공한 경우에만 다음 명령을 실행합니다"를 의미하므로 파일이 동일한 경우에만 실행됩니다.file1
fileName=${file##*/}
diff
&&
rm
재귀적으로 만들려면 다음을 사용한다고 가정합니다 bash
.
shopt -s globstar
cd /path/to/dirA/
for file in **; do
fileName=${file#*/}
echo diff -q <(sort "$file") <(sort /path/to/dirB/"$fileName") &&
rm /path/to/dirB/"$fileName"
done
또는 더 복잡하게는 디렉터리와 존재하지 않는 파일을 건너뜁니다.
shopt -s globstar
cd /path/to/dirA/
for file in **; do
if [ -d "$file" ]; then
echo "$file is a directory, skipping.";
else
fileName=${file#*/}
if [[ -e /path/to/dirB/"$fileName" ]]; then
echo diff -q <(sort "$file") <(sort /path/to/dirB/"$fileName") &&
rm /path/to/dirB/"$fileName"
fi
fi
done
답변2
fdupes
각 파일의 md5 해시를 계산하여 이를 수행하도록 특별히 설계된 와 같은 도구를 사용하십시오 . 동일한 디렉터리를 두 번 지정하면 데이터가 손실되는 등 몇 가지 주의 사항이 있으므로 여기서는 구체적인 세부 정보를 제공하지 않습니다. 예를 들어 /home/을 지정하는 경우그리고~/ 그동안 홈 디렉토리의 파일은 중복된 파일로 나열됩니다. 중복 항목을 자동으로 제거하도록 fdupes를 설정하면 홈 디렉터리의 모든 파일이 삭제됩니다!
아마도 가장 유용한 것은 man fdupes
CLI에 입력하는 것입니다. 그러면 모든 옵션이 포함된 매뉴얼이 표시되므로 이를 사용하는 가장 좋은 방법이 무엇인지, 어떤 옵션을 사용하고 싶은지, 사용하지 않을지 스스로 알아볼 수 있습니다. 이러한 경고는 두려워할 사항이 아니라 주의해야 할 사항입니다. 이는 아마도 이와 같은 도구의 기능을 더 잘 이해할 수 있으므로 이러한 도구를 사용하도록 훈련하는 가장 좋은 방법일 것입니다. 답변에 제공된 조언을 "맹목적으로" 복사하여 붙여넣으면 이러한 이점을 얻을 수 없습니다.
사용할 수 있는 도구가 없다면 배포판에서 이를 저장소에 제공할 가능성이 높습니다. 왜냐하면 이 도구는 많은 사람들이 선택하는 명령줄 도구이기 때문입니다.
fslint
또는 분명히 유용한 GUI 기반 도구인 이 도구를 고려해 볼 수도 있습니다 . 제가 직접 시도해본 적이 없어서 많이 말씀드릴 수는 없습니다.