내 목록에 있는 모든 파일이 포함된 디렉터리를 찾습니다.

내 목록에 있는 모든 파일이 포함된 디렉터리를 찾습니다.

동일한 상위 디렉터리에 있는 다른 4개의 파일을 참조하는 파일을 이동했습니다. 이제 내 빌드 환경에 같은 이름을 가진 파일이 많기 때문에 어떤 상위 디렉터리가 무엇인지 알아내려고 합니다. 하지만 나는 잘못된 파일을 복사하는 위험을 감수하고 싶지 않습니다. 그래서 Linux find 명령이나 다른 명령에 두 개 이상의 문자열과 일치하는 결과를 제공하도록 지시하는 방법이 있는지 궁금합니다. 그래서 파일이 포함된 위치와 일치하는 항목을 보고 싶습니다.

foo & bar & buz

필요한 공개 디렉토리를 얻기 위해 항상 이것을 grep에 입력할 수 있지만 더 쉬운 방법이 있다면 그것을 좋아할 것입니다. 그것은 다음과 같습니다:

common_direcoty/foo & common_directory/bar & common_directory/buz 

즉, 공용 디렉토리에서 이러한 파일의 복사본을 찾고 있습니다. 이름만 일치하는 파일을 찾는 것이 아닙니다.

이것은 내가 원하는 결과를 제공하는 명령의 출력입니다.

sansari@ubuntu:~/WORKING_DIRECTORY$ find . -name io.h -exec sh -c '[ -e "${0%/*}/kernel.h" ] && [ -e "${0%/*}/init.h" ]' {} \; -print
./include/linux/io.h
sansari@ubuntu:~/WORKING_DIRECTORY/include/linux$ ls module.h
module.h
sansari@ubuntu:~/WORKING_DIRECTORY/include/linux$ ls kernel.h 
kernel.h
sansari@ubuntu:~/WORKING_DIRECTORY/include/linux$ ls init.h
init.h
sansari@ubuntu:~/WORKING_DIRECTORY/include/linux$ ls io.h
io.h

답변1

한 가지 방법은 파일 이름 중 하나를 찾은 다음(아는 경우 가장 희귀한 이름 선택) 일치하는 항목을 필터링하여 다른 파일이 있는 파일 이름만 유지하는 것입니다.

find . -name foo -exec sh -c '[ -e "${0%/*}/bar" ] && [ -e "${0%/*}/buz" ] && echo "${0%/*}"' {} \;

작업 을 사용하려면 find셸 조각의 반환 코드를 사용할 수 있지만 이는 디렉터리가 아닌 첫 번째 파일에 적용됩니다. 예를 들어 다음 코드 조각은 양식의 출력을 인쇄합니다 ./path/to/foo.

find . -name foo -exec sh -c '[ -e "${0%/*}/bar" ] && [ -e "${0%/*}/buz" ]' {} \; -print

이름을 매개변수로 전달해야 하는 경우:

find_multiple_files () {
  root=$1; shift
  name1=$2; shift
  find "$root" -name "$name1" -exec sh -c 'dir=${0%/*}; for x; do [ -e "$dir/$x" ] || exit 1; done; echo "$dir"' {} "$@" \;
}
find_multiple_files . foo bar buz

또 다른 방법은 이름 목록을 생성하고 필터링하는 것입니다. 이는 다소 번거롭고 효율성이 떨어지지만 파일 이름 색인이 있으면 에서 전환할 수 있다는 장점이 있습니다 find. locate파일 이름에 개행 문자가 포함되어 있지 않다고 가정합니다.

locate foo |              # or: find -name foo
sed 's!/[^/]*$!!' |
xargs -I {} sh -c 'for x; do [ -e "$0/$x" ] || exit 1; done; echo "$0"' {} bar buz

답변2

나는 이 모든 것을 혼자서 할 수 있는 어떤 찾기 옵션도 모른다. grep을 사용하면 이를 달성할 수 있습니다. 찾으려는 모든 파일 이름을 다음 패턴을 사용하여 /tmp/files_to_find와 같은 별도의 파일에 넣습니다.

귀하의 경우 files_to_find는

\/foo$
\/bar$
\/buz$

그런 다음 다음 명령을 실행하십시오.

find root_dir_to_search_in | grep -f /tmp/files_to_find | xargs -I{} dirname {} | sort | uniq -c | grep `wc -l /tmp/files_to_find | awk '{print $1}'`

답변3

find모드를 그룹화 -or하고 -and다른 모드를 선택할 수 있어야 합니다 . 나는 그런 옵션을 사용하지 않지만

$ find . \( -name foo -or -name bar -or -name buz \) -and -path '*/G/*'|9 mc
./G/buz ./G/bar ./G/foo

여기서 G= common_directory. 파일 구조에 대해 이것을 테스트했습니다.

$ find . -name foo -or -name bar -or -name buz|9 mc
./G/buz ./G/bar ./G/foo ./F/buz ./F/bar ./F/foo

non-common_directory에도 foo, bar, baz가 있습니다.

9 mc명령은 출력을 조정하기 위한 p9p의 다중 열 포맷터입니다.

관련 정보