안녕하세요. 제 작업 명령은 다음과 같습니다:
grep -l "my text" file*.ext|xargs ls -lart
이 명령은 저에게 아주 효과적입니다. 다음과 같이 입력을 덜하면서 수행할 수 있는 셸 파일을 만들고 싶습니다.
fn "my text" file*.ext
이 쉘 스크립트 파일을 찾았습니다.
grep -l "$1" "$2"|xargs ls -lart
첫 번째 부분에서도 작동하지 않습니다.
grep -l "$1" "$2"
null을 반환
답변1
스크립트에는 3개 이상의 매개변수가 필요합니다.
쉘이 grep
명령을 실행하기 전에
grep -l "my text" file*.ext
파일 이름 와일드카드 패턴은 file*.ext
일치하는 모든 파일 이름으로 확장됩니다. 따라서 최종 명령줄 실행은 다음과 같습니다.
grep -l "my text" file1.ext file2.ext file3.ext
(패턴과 일치하는 파일인 경우)
따라서 스크립트는 다음과 같을 수 있습니다.
#!/bin/sh
pattern=$1
shift
grep -l -e "$pattern" "$@" | xargs ls -lrt
여기서 패턴은 변수에 저장된 다음 명령줄 인수 목록에서 제거됩니다. 나머지 인수는 파일 이름 목록(명령줄의 파일 이름 와일드카드 패턴이 일치하는 경우)이며 "$@"
.
큰따옴표를 사용하세요 $@
. 그러면 $@
개별적으로 인용된 명령줄 인수 목록이 확장됩니다.
목록에 명시적인 파일 이름을 제공할 때 필요하지 않으므로 해당 -a
옵션을 제거했습니다 . 또한 패턴을 지정하기 위해 with를 ls
사용합니다 . 첫 글자에 대시( )가 있는 패턴은 혼란스러울 수 있기 때문입니다 .grep
-e
-
grep
find
정렬이 아닌 경우 파이핑 대신 다음을 사용하는 것이 좋습니다 (공백과 개행 문자가 있는 파일 이름을 올바르게 처리).
find . -type f -name "$filepattern" -exec grep -q -e "$pattern" {} ';' -ls
$filepattern
이는 의 콘텐츠 와 일치하는 이름과 의 콘텐츠와 일치하는 콘텐츠를 가진 파일을 찾은 다음 유사한 출력을 $pattern
생성합니다 . ls -l
검색은 현재 디렉터리에서 반복적으로 수행됩니다.
스크립트의 일부로:
#!/bin/sh
pattern=$1
filepattern=$2
find . -type f -name "$filepattern" -exec grep -q -e "$pattern" {} ';' -ls
이것스크립트는 호출될 때 쉘이 파일 이름 글로빙 패턴을 확장하지 않는 방식으로 호출되어야 합니다.
$ ./script.sh 'my text' 'file*.ext'
답변2
더 안전하게 만들려면 GNU 확장을 사용하세요.
#! /bin/sh -
pattern=${1?pattern required}; shift
: "${1?no filename specified}"
grep -l --null -e "$pattern" -- "$@" |
xargs -r0 ls -lrtd --
--null
/를 사용하면 -0
공백, 따옴표 또는 백슬래시가 포함된 파일 이름과 관련된 문제를 피할 수 있습니다.
이렇게 하면 -e "$pattern"
패턴으로 시작하는 문제를 피할 수 있습니다 -
.
를 사용하면 --
로 시작하는 파일 이름 문제를 피할 수 있습니다 -
.
를 사용하면 -d
디렉터리 유형의 파일이 일치할 때 발생할 수 있는 혼란을 피할 수 있습니다.
를 사용하면 -r
일치하는 파일이 없는 경우 현재 디렉터리 나열을 피할 수 있습니다.
파일 수가 많은 경우 파일의 일부 목록에 대해 여러 호출을 실행하도록 선택할 수 있습니다 xargs
. 즉, 출력이 시간별로 올바르게 나열되지 않을 수 있습니다.ls
또한 이는 stdin이 이지만 호출되는 파일이 -
현재 디렉토리에 있음을 의미합니다. grep
GNU는 이를 출력합니다(또는 이를 귀하의 언어로 번역합니다). 현재 디렉터리에서 호출되는 파일을 지정하려면 .-
ls
grep -l
(standard input)
-
./-
-