일부 파일이 포함된 디렉터리가 있습니다. 각 파일에 특정 단어가 존재하는지 알고 싶습니다.
$1
내가 매개변수로 제공한 디렉토리입니다
예를 들어./myscript.sh /mnt/c/User/er/Desktop/shows
이 코드를 작성했지만 터미널에 다음 오류가 표시됩니다.[: it21754 :binary operator expected
#!/bin/bash
for a in $( find "$1" -type f )
do
if[ egrep 'it21754' $a ]
then
echo "0"
else
echo "1"
fi
done
답변1
출력을 반복하지 마십시오 find
. 전체 find
명령이 완료되고 생성되어야 하므로 이는 다소 우아하지 않습니다.모두루프가 첫 번째 반복을 실행하기 전의 출력입니다. 또한 스크립트는 공백이 포함된 파일 이름을 올바르게 처리하지 않습니다. 명령 대체의 결과는 공백으로 분할되어 루프에 대한 단어를 생성합니다.
대신 find
다음과 같이 명령이 루프의 파일 이름을 생성하도록 합니다.
find "$1" -type f -exec sh -c '...loop here...' sh {} +
우리는 곧 이 주제로 돌아올 것입니다.
그냥 문법
if[ egrep 'it21754' $a ]
조금 이상합니다. egrep
여기서는 꼭 필요하지 않습니다( grep
충분합니다).
"이상하다"는 말은 [ ... ]
테스트가 일반적으로 다음과 같 [ op arg ]
거나 or and 와 같은 연산자가 문자열 인 [ arg op arg ]
것처럼 보인다는 것입니다 . 확장되는 모든 항목을 사용하면 오류 가 발생합니다. 이 조건에서는 실제로 실행할 수도 없고 실행할 필요도 없습니다.op
-f
-eq
=
arg
egrep
it21754
$a
egrep
올바른 if
진술은
if grep -qwF 'it21754' "$a"; then
echo 0
else
echo 1
fi
플래그는 일치를 위해 정규식( ) 대신 문자열 비교를 사용하는 Quiet( )을 -qwF
만들고 일치하는 문자열이 하위 문자열( )이 아닌 완전한 단어가 되도록 보장합니다 . 여기서는 종료 상태를 사용하여 0(일치) 또는 1(일치 없음)을 출력할지 여부를 선택합니다.grep
-q
-F
-w
grep
또한 파일 이름에 공백이나 파일 이름 와일드카드가 포함되어 있는 $a
경우를 대비해 큰따옴표를 넣었습니다 ."$a"
흥미롭게도 이 숫자는 grep
어쨌든 종료 상태에 사용되므로 전체 프로세스를 다음과 같이 단축할 수 있습니다.
grep -qwF 'it21754' "$a"
echo "$?"
이 $?
변수는 가장 최근에 실행된 명령의 종료 상태를 보유합니다.
이것을 find
명령에 연결하면 다음과 같은 결과를 얻을 수 있습니다.
find "$1" -type f -exec sh -c '
for a do
grep -qwF "it21754" "$a"
echo "$?"
done' sh {} +
파일에 주어진 단어가 포함되어 있는지 여부에 따라 많은 1과 0이 생성됩니다. 하지만 0이나 1 대신 해당 단어가 포함된 파일의 파일 이름을 찾고 있을 수도 있다고 생각합니다. 이를 위해 우리는 사용할 수 있습니다
find "$1" -type f -exec grep -lwF 'it21754' {} +
여기서는 ("dash ell") -q
로 변경 하겠습니다 . 그러면 찾은 파일이 -l
호출 되고grep
grep
오직주어진 단어를 포함하는 출력 파일 이름입니다. sh -c
단일 유틸리티를 호출하기 때문에 더 이상 이 비트가 필요하지 않습니다 .grep
그리고 echo
).
물론, 당신도 같은 일을 할 수 있습니다오직 grep
:
grep -R -lwF 'it21754' "$1"
를 사용하면 -R
명령 grep
줄에 지정된 하위 디렉터리를 반복적으로 검색합니다.
-w
및 -R
플래그는 grep
표준이 아니지만 가장 일반적인 변형으로 구현된다는 점에 주목할 가치가 있습니다 grep
.
관련된: