z/xy가 아닌 모든 xy의 파일 목록을 얻는 방법은 무엇입니까?

z/xy가 아닌 모든 xy의 파일 목록을 얻는 방법은 무엇입니까?

Settings.json이 컴퓨터에는 많은 파일이 있습니다.

나는 이 모든 사람들의 목록을 얻기 위해 다음 방법을 사용합니다.

find / -name "Settings.json" 2>&-

그러나 그 중 일부는 에 있습니다 Api. 예를 들면 다음과 같습니다.

/ClubApi/Settings.json
/CrmApi/Settings.json

속하지 않는 한 모두 삭제하고 싶습니다. Api... 그렇게 할 수 없습니다.

나는 시도했다:

find / -name "Settings.json" 2>&- | xargs grep -v Api 

그러나 경로 필터링에는 작동하지 않습니다 Api.

어떻게 해야 하나요?

답변1

우선 이런 습관을 들이지 마세요폐쇄2>&-오류를 무시하려면 표준 오류 스트림을 사용하십시오. 로 리디렉션하는 것이 /dev/null더 안전합니다 2>/dev/null. 일부 명령은 닫힌 스트림에 쓰기를 시도하고 실패하면 종료됩니다.

예를 들어 참조하십시오.

{ echo 'error' >&2 && echo 'output'; } 2>&-

(아무것도 출력하지 않음) 대

{ echo 'error' >&2 && echo 'output'; } 2>/dev/null

(출력 output).


-path영향을 주지 않으려는 파일을 방지하려면 테스트를 사용하세요 .

LC_ALL=C find / -type f ! -path '*Api/Settings.json' -name 'Settings.json' -print

또는 *Api근처에 있고 싶지 않다면 다음 디렉토리를 완전히 피하십시오.

LC_ALL=C find / -name '*Api' -prune -o -type f -name 'Settings.json' -print

술어는 -prune검색 트리에서 분기를 "자르기"(잘라내기, 제거)하므로 위 find명령은 이름이 일치하는 디렉토리에 들어가지도 않습니다 *Api.

-print-exec rm {} +실제로 파일을 삭제 하려면 위의 명령을 변경하세요 .

답변2

삭제 작업을 수행 중이므로 파일 목록을 먼저 테스트하는 것이 가장 좋습니다.

find결과를 개선하려면 부정적인 옵션을 사용하십시오 -not -path.

find / -type f (-not -path "*[Aa]pi*") -and -name "Settings.json"  2>/dev/null

필터 find출력grep

find / -type f -name "Settings.json"  2>/dev/null | grep -v "[Aa]pi"

올바른 목록을 얻은 후:

가장 간단한 방법은 명령에 -delete작업을 추가하는 것입니다 find.

이것은극도로 위험하다운영 중/

find / -type f (-not -path "*[Aa]pi*") -and -name "Settings.json" -delete 2>/dev/null

보다 신중한 삭제 명령 rm은 다음과 같습니다 $(calculated list).

rm $(find / -type f (-not -path "*[Aa]pi*") -and -name "Settings.json"  2>/dev/null)

답변3

나는 다음 방법을 사용하여 모든 사람들의 목록을 얻습니다.find …

find에 의존하는 대신 쉘을 사용하여 이 작업을 수행할 수도 있습니다.

#!/bin/bash
# To enable ** globbing
shopt -s globstar 

filename=Settings.json
for file in **/${filename} ; do
  if ! [[ "${file}" =~ Api/${filename}$ ]]; then
    # Do something, e.g. 
    # echo "${file}"
    # But beware! Files' and directories' names can contain newlines,
    # so I'd recommend either directly working on the file as you have it:
    # jq -r '.[0].command' < "${file}"
    # or printing it with the zero byte as terminator, instead of newline:
    # printf "%s\0", "${file}"
  fi
done

관련 정보