쉘 내에서 함수 찾기

쉘 내에서 함수 찾기

find다음과 같은 최소 작업 예제를 사용하여 함수 안에 넣고 함수에 전달된 인수를 캡처해 보았습니다 .

기능 DO
{
    ls $(find .-type f -name "$@" -exec grep -IHl "TODO" {} \;)
}

그러나 실행하면 DO *.tex"find: path must beforeexpression:"이 표시됩니다. 하지만 내가 직접 이 작업을 수행하면 다음과 같습니다.

ls $(find .-type f -name "*.tex" -exec grep -IHl "TODO" {} \;)

그런 다음 "TODO"가 포함된 모든 TeX 파일을 얻습니다.

DO함수에서 많은 것을 시도했습니다. 예를 들어 ,,, \"$@\"따옴표 '$@'를 변경했지만 동작은 여전히 ​​동일합니다.

그렇다면 함수 내에서 작업을 강제로 찾으려면 어떻게 해야 할까요?

답변1

코드에 몇 가지 문제가 있습니다.

  1. 패턴이 현재 디렉터리의 파일 이름과 일치하는 경우 *.tex이 함수가 호출될 때 패턴이 확장됩니다. 이 함수를 호출할 때 DO패턴을 '*.tex', "*.tex"또는 으로 참조해야 합니다.\*.tex

  2. 불필요한 ls. 이미 두 가지가 모두 있으며 find발견 grep된 파일의 경로 이름을 보고할 수 있습니다.

  3. -name "$@""$@"단일 항목을 포함하는 경우에만 올바르게 작동합니다. 이용하시면 더 좋을 것 같습니다 -name "$1". 여러 모드를 허용하는 솔루션은 아래를 참조하세요.

이 함수는 다음과 같이 작성할 수 있습니다.

DO () {
   # Allow for multiple patterns to be passed,
   # construct the appropriate find expression from all passed patterns

   for pattern do
       set -- "$@" '-o' '-name' "$pattern"
       shift
   done

   # There's now a -o too many at the start of "$@", remove it
   shift

   find . -type f '(' "$@" ')' -exec grep -qF 'TODO' {} ';' -print
}

이 함수를 이렇게 호출하세요

DO '*.tex' '*.txt' '*.c'

실행하게 해줄게

find . -type f '(' -name '*.tex' -o -name '*.txt' -o -name '*.c' ')' -exec grep -qF TODO {} ';' -print

파일에 문자열이 포함되어 있으면 해당 파일 이름 접미사가 있는 파일에 대한 경로 이름 목록이 생성됩니다 TODO.

찾은 경로 이름을 인쇄 grep하는 대신 사용하려면 비트를 로 변경하십시오 . 이는 특히 특정 표현식과 일치하는 파일 이름이 많은 경우 더욱 효율적입니다. 두 경우 모두 를 사용할 필요가 전혀 없습니다 .find-exec ... -print-exec grep -lF 'TODO' {} +ls


사용자가 사용할 수 있도록

DO tex txt c

귀하의 기능은 다음과 같이 변경될 수 있습니다.

DO () {
   # Allow for multiple patterns to be passed,
   # construct the appropriate find expression from all passed patterns

   for suffix do
       set -- "$@" '-o' '-name' "*.$suffix"   # only this line (and the previous) changed
       shift
   done

   # There's now a -o too many at the start of "$@", remove it
   shift

   find . -type f '(' "$@" ')' -exec grep -qF 'TODO' {} ';' -print
}

답변2

함수에 인수를 인용해야 합니다. 그렇지 않으면 셸이 인수를 확장하고 함수는 와일드카드 마스크 대신 파일 목록을 가져옵니다.

DO "*.tex"

그러면 매개변수가 하나만 있으므로 "$1"대신 사용할 수 있습니다 ."$@"

관련 정보