2014-06-12 2 views
0

나는이 패턴에서, 비슷한 이름의 파일이있는 디렉토리가 :파일 인스턴스 두 개를 제외한 모든 인스턴스를 삭제하는 방법은 무엇입니까?

00002_930831_fa.ppm 00398_940422_fa.ppm 00714_960530_fa.ppm 
00002_930831_fb.ppm 00398_940422_fb.ppm 00714_960530_fb.ppm 
00002_931230_fa.ppm 00399_940422_fa.ppm 00714_960620_fa.ppm 
00002_931230_fb.ppm 00399_940422_fb.ppm 00714_960620_fb.ppm 
00002_940128_fa.ppm 00400_940422_fa.ppm 00715_941201_fa.ppm 
00002_940128_fb.ppm 00400_940422_fb.ppm 00715_941201_fb.ppm 
00002_940422_fa.ppm 00401_940422_fa.ppm 00715_941205_fa.ppm 
00002_940422_fb.ppm 00401_940422_fb.ppm 00715_941205_fb.ppm 
00002_940928_fa.ppm 00402_940422_fa.ppm 00716_941201_fa.ppm 
00002_940928_fb.ppm 00402_940422_fb.ppm 00716_941201_fb.ppm 

내가 뭘해야 예를 들어 00002 샘플의 두 인스턴스를 제외하고 모두 제거되도록 (중요하지 않는 것) 예를 들어 00002_930831_fa.ppm00002_930831_fb.ppm으로 남았습니다. 문제는 모든 샘플, 00003, 00004 등에 대해이 작업이 필요하다는 것입니다. 각 샘플마다 두 개의 파일이 있어야합니다.

나는 find으로 시도했지만, 내 조건에 얼마나 열중하는지 잘 모르겠습니다.

간단히 명령을 파이핑하여 해결할 수 있습니까, 아니면 bash 스크립트로 해결해야합니까?

ls 00002_* | tail -n +3 | xargs rm 
+0

은 rm $가 될 수 (LS 00002_ * | 꼬리 -n 3) 당신은 거기에 그렙을 추가 할 수 있습니다 – Majenko

답변

1

:

#!/bin/bash 

[[ BASH_VERSINFO -ge 4 ]] || { 
    echo "You need Bash 4.0 or newer to run this script." >&2 
    exit 1 
} 

declare -A COUNTER=() 

for A in *.ppm; do 
    IFS=_ read I __ <<< "$A" 
    ((++COUNTER[$I] > 2)) && rm "$A" 
done 

시뮬레이션 :

Skip 00002_930831_fa.ppm 
Skip 00002_930831_fb.ppm 
rm 00002_931230_fa.ppm 
rm 00002_931230_fb.ppm 
rm 00002_940128_fa.ppm 
rm 00002_940128_fb.ppm 
rm 00002_940422_fa.ppm 
rm 00002_940422_fb.ppm 
rm 00002_940928_fa.ppm 
rm 00002_940928_fb.ppm 
Skip 00398_940422_fa.ppm 
Skip 00398_940422_fb.ppm 
Skip 00399_940422_fa.ppm 
Skip 00399_940422_fb.ppm 
Skip 00400_940422_fa.ppm 
Skip 00400_940422_fb.ppm 
Skip 00401_940422_fa.ppm 
Skip 00401_940422_fb.ppm 
Skip 00402_940422_fa.ppm 
Skip 00402_940422_fb.ppm 
Skip 00714_960530_fa.ppm 
Skip 00714_960530_fb.ppm 
rm 00714_960620_fa.ppm 
rm 00714_960620_fb.ppm 
Skip 00715_941201_fa.ppm 
Skip 00715_941201_fb.ppm 
rm 00715_941205_fa.ppm 
rm 00715_941205_fb.ppm 
Skip 00716_941201_fa.ppm 
Skip 00716_941201_fb.ppm 

주 : 시험 그것을 제 일부에 더미 파일.

는 생각 가자 :

IFS=_ read I __ <<< "$A" 

단지

I=${A%%_*} 
3

그냥 head 또는 tail이 파일 이름 목록을 필터링하는 데 사용 rm. bash는 버전 4

while read -r sample; do 
    matching_files=(${sample}_*) 
    # To make sure at least two files survive: 
    ((${#matching_files[@]} > 2)) && rm "${matching_files[@]:2}" 
done < samples.txt 
+0

00002. 그는 00002 샘플의 파일 만 찾고 있습니다. 그래서 :'ls | grep 00002 | 꼬리 - n + 3 | xargs rm' –

+0

OP는 00002 개의 파일을 원했기 때문에 00002_ *와 그 밖의 모든 것들을 원했습니다. – MJB

+0

@MJB : 그냥 해냈어. 고마워. – nneonneo

2

다음, 일치하는 모든 파일 이름을 포함하는 배열을 만들려면 인수로 처음 두 요소를 제외한 전부를 통과하고 문자열 매개 변수 확장 연산자를 사용

+0

이것은 잘 작동합니다. 감사합니다! 유일한 문제는 일부 샘플에는 두 개의 파일 만 있고 코드는 삭제하는 것입니다 ... 나는 일종의 카운터를 사용해야 할 것 같습니다. – mkolarek

0

: 당신이 그것을 삭제할 수있는 권한 파일을 선택하는 것에 만족하는 경우

declare -A files 
for f in *ppm; do 
    files[${f%%_*}]+="$f " 
done 
for i in "${!files[@]}"; do 
    set -- ${files[$i]} 
    shift 2 
    (($# > 0)) && echo rm $* 
done 

echo를 제거합니다.

공백이있는 파일 이름이 있으면 작동하지 않습니다. 연관 배열을 사용

관련 문제