쉘 스크립트의 코드 조각
fname=$(sed 's/(.*//' <<< $p | awk '{ print $NF }')
if [[ $fname == *['!'@#\$%^\&*()_+]* ]]
then
flag1=0
fi
여기서 $p는 텍스트 파일의 한 줄입니다.
p-값은 다음과 같습니다. >= (short)BigBlock * DISK_SIZE + Size)
위의 쉘 스크립트가 p 값에 대해 실행되면 터미널에서와 같은 쓰레기 결과가 나타납니다.
>= (short)BigBlock file1 file2 file3 DISK_SIZE + Size)
여기서 file1 file2 file3은 폴더의 파일입니다.
내 생각엔 *가 ls 명령으로 처리되는 것 같습니다.
가능한 해결책은 무엇입니까
답변1
요약: echo $p
코드에 이와 같은 부분이 있을 수 있습니다. 큰따옴표가 필요합니다 $p
.
아니요, 명령 *
으로 간주되지 않습니다 . ls
그러나 (질문에 표시된 코드가 아닌) 어딘가에 따옴표 없이 사용되므로 파일 이름 글로빙 패턴으로 처리됩니다.
p
값을 할당 및 사용할 때, 문자열을 보호하기 위해 적절한 따옴표를 사용할 때는 주의가 필요합니다 .
파일 이름 globbing 패턴은 이 문자열에서 확장되지 않습니다.
$ cat <<< *
*
$p
따라서 호출 시 따옴표 없이 사용해도 문제가 없습니다 sed
. 그러나 명시적 참조 변수 확장은 거의 항상 더 좋습니다. $fname
테스트에서 참조되지 않은 사용 도 참조하세요 . 반드시 큰따옴표로 묶어야 합니다.
스크립트가 텍스트를 출력한다고 말씀하셨어요
>= (short)BigBlock file1 file2 file3 DISK_SIZE + Size)
질문에 표시된 스크립트에서는 해당 문자열이 출력되지 않습니다. 이것은 당신이하는 일 때문일 수 있습니다
echo $p
스크립트의 다른 곳에서.
이번에도 큰따옴표를 사용하세요 $p
.
echo "$p"
이렇게 하면 쉘이 *
해당 값에 대해 파일 이름 글로빙(확장)을 수행하는 것을 방지할 수 있습니다.
일반적으로 정적 문자열, 변경 가능한 데이터 echo
에만 해당됩니다 .printf
printf '$p is "%s"\n' "$p"
마지막 요점과 관련:왜 printf가 echo보다 나은가요?
답변2
먼저 실제 $p 값 문자열을 기다리는 동안 $p를 인용해야 합니다.
fname=$(sed 's/(.*//' <<< "$p" | awk '{ print $NF }')
또한 sed 's/(.*//'
문자열의 끝도 일치됩니다.
f='(something) and more stuff';sed 's/(.*//' <<< "$f"
결과는 물론 빈 문자열입니다.
f='(something)-and more stuff';sed 's/([^)]*)//' <<< "$f"
결과: - 기타