와일드카드가 감지되면 명령이 제대로 작동하지 않는 이유는 무엇입니까?

와일드카드가 감지되면 명령이 제대로 작동하지 않는 이유는 무엇입니까?

쉘 스크립트의 코드 조각

 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"

결과: - 기타

관련 정보