bash의 파일 이름 확장 메커니즘에서 일부 파일을 제외하는 방법은 무엇입니까?


14

루트 디렉토리에 우분투 파일 시스템 디렉토리가 있고 실수로 수백 개의 파일을 루트 디렉토리에 복사했습니다.

직관적으로 파일 시스템을 제외하여 복사 된 파일을 제거하려고했습니다.

rm -rf !{bin,sbin,usr,opt,lib,var,etc,srv,libx32,lib64,run,boot,proc,sys,dev} ./.

bu 작동하지 않습니다. 전체를 삭제하면서 일부 디렉토리를 제외시키는 올바른 방법은 무엇입니까?

편집 : 무엇을 해야할지 몰라 여기 명령을 시도하지 마십시오!


1
어떤 쉘을 사용하고 있습니까? 파일 이름 글 로빙은 멋진 일을 할 때 쉘에 의존합니다.
Kusalananda

2
대답은 아니지만 예를 들어 사용합니다 mc. 로 모든 항목을 *선택한 다음 -또는 Insert키를 사용 하여 특정 파일을 선택 취소하십시오 .
pbm

1
'mc'가 무엇인지 설명 할 수 있습니까?
MikeP

@Kusalananda 그것은/bin/bash
Kenn

3
@MikeP : mcNorton Commander의 유용한 모방 인 Midnight Commander입니다. 터미널에서 실행됩니다. 자정 사령관과 노턴 사령관은 정통 파일 관리자의 예 입니다.
AlexP

답변:


21

당신이 사용하고 있기 때문에 bash:

shopt -s extglob
echo rm -rf ./!(bin|sbin|usr|...)

echo전체 시스템을 손상시킬 수있는 것을 실행할 때 명령 줄의 시작 부분에 추가하는 것이 좋습니다 . 결과에 만족하면 제거하십시오.

참고 : 위 명령은 숨겨진 파일 (점으로 시작하는 이름)을 제거하지 않습니다. 당신도 그들을 제거하려면 다음 dotglob옵션 도 활성화하십시오 :

shopt -s dotglob

파일 시스템을 성공적으로 정리하는 데 사용했습니다. 처음에는 디렉토리에서 테스트했습니다. 나는 또한 rm -rf ./!(bin,sbin,..)쉼표를 분리 하려고 시도했지만 모든 디렉토리를 제거합니다.
kenn

!(...)구문 은 무엇입니까 ? 예제에서 직관적으로 ls ./!(*/)파일 만 나열 한다고 생각 했지만 그렇게 작동하지는 않습니다.
giusti

@giusti이 구문은 파일 이름 확장 메커니즘에서 확장 된 패턴 일치입니다. 경로 이름 확장 장의 bash 매뉴얼에서 설명을 찾을 수 있습니다. 별 *이나 다른 globs 와 마찬가지로 파일 유형 만 제외하고 이름 만 제외 할 수 있습니다 .
jimmij

12

이 명령은 다음의 모든 비 디렉토리를 표시합니다 /.

find / -maxdepth 1 -type f

당신이 만든 후에는 절대적으로 확실 어떤 파일을 유지할 것인지를이없는, 당신은 사용할 수 있습니다 :

find / -maxdepth 1 -type f -delete

더 안전한 방법은 보존하려는 항목을 삭제하지 않도록 다른 위치로 옮기는 것입니다.

mkdir /root/preserve
find / -maxdepth 1 -type f -exec mv -- "{}" /root/preserve/\;

파일뿐만 아니라, 당신은 또한 가지고있는 경우 디렉토리 는 파일 시스템의 루트에 추가 한 것으로, 이것은 수있는 자동화에서 LSB 디렉토리 제외하여 자동화 할 수 mv또는 rm에 퍼지 것들로 우리부터있는 거 거래, 정직하게,하지만를 파일 시스템의 근원이라면, 가능한 경우 수동으로 수행하는 것이 좋습니다.

이것이 가능하지 않은 경우 다음과 같은 방법으로 트릭을 수행 할 수 있습니다.

#!/bin/bash
declare -a excludes
for item in root sys 'lost+found' mnt home proc etc opt boot lib lib64 libx32 sbin media srv dev var usr bin tmp run; do
    excludes+=("$item")
done
if ! [[ -d /root/preserve ]]; then
    mkdir -p /root/preserve
fi
IFS="\n"
for item in find / -type d -maxdepth 1; do
    really=true
    for exclude in ${excludes[@]}; do
        if [[ "$exclude" == "${item#/}" ]]; then
            really=false
        fi
    done
    if [[ "true" == "$really" ]]; then
        mv -- "$item" /root/preserve/
    fi
done

비명 테스트를 통과 한 후 (즉, 시스템이 계속 실행 중이고 고뇌하지 않는 경우)의 내용을 제거 할 수 있습니다 /root/preserve/.

중요 사항 : 당신이 무엇을하든,의 순열을 실행하는 것에 대해 생각조차하지 마십시오 rm -fr [ANYTHING GOES HERE] /.


솔루션은 파일 만 삭제하지만 폴더도 있습니다.
kenn

1
한 번 이상, 나는 조준하게 조롱당하는 것에 대한 비명을 들었습니다 rm. 와 같은 스크립트 rm -fr $somepath/somepath그것에서 초기화되지. 나는 이것이 얼마나 중대한지를 표현하는 데 더 나아갈 수 있었지만 내 훈계에서 가족 친화적으로 유지하기로 선택했습니다.
DopeGhoti

3

이렇게하면 작업이 완료되어야합니다 (OP가 요청하는 것과 같은 방식은 아님).

ls -1 >1.txt
pico 1.txt 

유지하려는 모든 파일 / 디렉토리를 제거하십시오.

xargs rm < 1.txt

파일의 이름 형식, 날짜 또는 다른 이름이 모두 같은 경우 다른 방법이 있습니다.

inode를 살펴보고 ls -i 정렬을 통해 순차적 인지 확인하고, 그렇다면 새 파일에 더 큰 inode가 있습니다. 그런 다음 위와 동일한 유형의 프로세스를 사용하십시오.

ls -iF1 | sort |cut -c10- | grep -vE "\/|\@" >i.txt   #This part removes entries that are not regular files, such as directories and links.  
pico i.txt
xargs rm < i.txt

위의 cut 명령에서 먼저 inode 목록을 확인하여 올바른 양인지 확인하십시오.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.