텍스트 파일의 한 줄에 있는 문자열 집합을 사용하여 찾기 명령을 수행하는 방법

텍스트 파일의 한 줄에 있는 문자열 집합을 사용하여 찾기 명령을 수행하는 방법

이것은 fnames.txt라는 텍스트 파일의 내용입니다.

"SAMPLE_NIKE_856_20170703*"
"SAMPLE_ADIDAS_856_20170702*"
"SAMPLE_ANTA_856_20170630*"
"SAMPLE_JORDAN_856_20170627*"
"SAMPLE_CONVERSE_856_20170229*"

다음은 fn.sh라는 스크립트입니다.

#!/bin/sh
#
#
while read LINE
do
    find -name "$LINE"
done < fnames.txt

아무것도 반환하지 않습니다.

내가 원하는 것은 각 줄에서 스크립트가 find 명령을 실행하고 출력을 files.txt라는 다른 텍스트 파일에 저장하는 것입니다. 예를 들면 다음과 같습니다.

라인 1:

find -name "SAMPLE_NIKE_856_20170703*"

그런 다음 찾고 있는 파일 이름을 반환합니다.

./SAMPLE_NIKE_856_20170703_80_20_304_234_897.dat

2호선:

find -name "SAMPLE_ADIDAS_856_20170702*

그런 다음 찾고 있는 파일 이름을 반환합니다.

./SAMPLE_ADIDAS_856_20170702_56_98_123_245_609.dat

스크립트는 find 명령의 모든 행이 실행될 때까지 계속 실행됩니다.

답변1

그 이유는 쉘이 다양한 확장과 인용을 처리하는 순서 때문입니다. 직접 입력하면

find . -name "foo*"

쉘은 따옴표를 제거하고 foo*이를 인수로 에 전달합니다 find.

따옴표가 없으면 쉘은 *첫 번째 항목에 와일드카드를 수행하여 여러 일치 항목이 나올 수 있으므로 find.따라서 따옴표를 사용하는 것이 현명합니다.

read그러나 파일에서 문자열을 가져 오면 변수에 따옴표가 포함됩니다. 이제 당신이 할 때

> echo $LINE
"foo*"
> echo "foo*"
foo*
> find . -name $LINE

의 따옴표와 달리 의 따옴표는 $LINE제거되지 않음 을 알 수 있습니다 echo "foo*". 이는 쉘이 먼저 echo $LINE(따옴표 없이) 따옴표를 처리한 다음 변수 대체를 수행하여 행이 읽혀지지만 echo "foo*"이제 따옴표가 여전히 남아 있기 때문입니다.

따라서 find따옴표가 포함된 파일을 찾으게 됩니다. 해결책은 파일에서 따옴표를 제거하는 것입니다. 거기에는 인용이 필요하지 않으며 전체 줄이 변수로 이동됩니다.

답변2

로 변경 IFS:

while IFS=\" read -r x LINE x; do
   find . -name "$LINE"
done < fnames.txt

$LINE이렇게 하면 기본적으로 제대로 작동하는 데 필요한 따옴표가 제거됩니다 . find그것이 하는 일은 $LINE에 나타나지 않도록 읽는 줄을 따옴표로 나누는 것입니다.

답변3

마침내 답을 찾았습니다. 다른 디렉토리에서 스크립트를 실행하고 있으므로 fnames.txt의 전체 파일 경로를 /path/to/my/fnames.txt로 호출하면 됩니다.

#!/bin/sh
#
#
while read -r LINE
do
    find -name "$LINE"
done < /path/to/my/fnames.txt

산출:

./SAMPLE_NIKE_856_20170703_80_20_304_234_897.dat
./SAMPLE_ADIDAS_856_20170702_56_98_123_245_609.dat

관련 정보