작업 명령을 매개변수를 가져오는 쉘 스크립트 파일로 변환

작업 명령을 매개변수를 가져오는 쉘 스크립트 파일로 변환

안녕하세요. 제 작업 명령은 다음과 같습니다:

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이 이지만 호출되는 파일이 -현재 디렉토리에 있음을 의미합니다. grepGNU는 이를 출력합니다(또는 이를 귀하의 언어로 번역합니다). 현재 디렉터리에서 호출되는 파일을 지정하려면 .-lsgrep -l(standard input)-./--

관련 정보