이것은 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