csh에서 메타문자, find 및 다른 변수를 포함하는 문자열로 변수를 설정하는 중에 문제가 발생했습니다.

csh에서 메타문자, find 및 다른 변수를 포함하는 문자열로 변수를 설정하는 중에 문제가 발생했습니다.

나는 프로젝트에서 csh를 사용하고 있으며(죄송합니다. 강제로 사용해야 합니다), 내 스크립트의 구성 요소는 대부분의 기능을 위해 다음과 같은 변형을 사용합니다.

find . -maxdepth 1 -not -type d | awk '{gsub(/.\//,"")}1' | grep $userID

이는 내 스크립트에서 예상대로 작동하지만 표현식과 grep 결과를 변경할 수 있도록 변수로 설정해야 합니다(이 문자열을 수정하는 큰 스위치 문이 있습니다). 나는 많은 것을 시도했지만 제대로 작동하지 않는 것 같습니다. 따라서 CSH를 사용하는 대신 명령을 변수에 로드했지만(다시 한번 죄송합니다.) 이 매우 특정한 경우에는 가능하면 작동하도록 해보고 싶었습니다. 나는 그것이 단지 인용/형식 문제인 것처럼 느낍니다. 그렇지 않으면 완전히 포기했을 것입니다.

내가 한 일은 다음과 같습니다.

큰따옴표:

set findString = "find . -maxdepth 1 -not -type d | awk '{gsub(/.\//,"")}1' | grep $userID"

이것은 잘 울리지만 find를 실행할 때 다음 오류가 발생합니다.

찾기: 경로는 표현식 앞에 와야 합니다. |

쉘이 명령을 실행하기 전에 명령을 확장하려고 시도한다는 것을 알고 있지만 이 문제를 해결하는 방법을 잘 모르겠습니다(작동시키기 위해 인용할 수 없는 것 같습니다). 나는 다음을 통해 그것을 따옴표로 묶어 보았습니다.

set findString = "find . -maxdepth 1 -not -type d \"|\" awk '{gsub(/.\//,"")}1' | grep $userID"
set findString = "find . -maxdepth 1 -not -type d \"| awk '{gsub(/.\//,"")}1' | grep $userID\""
set findString = "find \". -maxdepth 1 -not -type d | awk '{gsub(/.\//,"")}1' | grep $userID\""
set findString = "\"find . -maxdepth 1 -not -type d | awk '{gsub(/.\//,"")}1 | grep $userID'\""

그리고 다음을 각각 받았습니다:

견줄 나위 없는".

그런 다음 작은따옴표를 시도했지만 에코할 수 없는 것 같습니다.

set findString = 'find . -maxdepth 1 -not -type d | awk \'{gsub(/.\//,"")}1\' | grep $userID'
echo $findString

다시 한번: 비교할 수 없는'.

이 시점에서 다시 큰따옴표를 사용해 보았지만 모든 csh 메타 문자를 이스케이프 처리했습니다.

set findString = "find\ .\ \-maxdepth\ 1\ \-not\ \-type\ d\ \|\ awk\ \'\{gsub(/.\\//,\"\"\)}1\'\ \|\ grep\ \$userID"

아니요. 그래서 나는 참조한 다른 스레드를 찾았습니다.이 유용한 문서인용하고 다양한 방법으로 구현해 보세요. 결국 변수를 꺼내고 find변수의 나머지 문자열을 검색 옵션으로 로드했습니다. 나는 또한 grep그것을 제로화하기 위해 튜브를 벗겨 냈습니다 . 그것은 다음과 같습니다:

set findString = ( \( -maxdepth 1 -not -type d | awk '{gsub(/.\//,"")}1' \) )
echo $findString
find . "${findString}"

find작동 하더라도 올바르게 평가되지는 않습니다. 나는 이것을 할 수 있는 방법이 있어야 한다고 생각한다.

나는 붙어있다. 이에 대한 도움을 주시면 감사하겠습니다. CSH를 사용하여 이중 잔학 행위를 저지르고 이 명령 문자열을 var에 로드한 것에 대해 다시 한 번 사과드립니다.

답변1

|변수에 a를 넣고 변수가 확장된 후에는 사용되지 않는 것으로 해석할 수는 없다고 생각합니다 eval.

따라서 당신이 할 수 있는 일은 매개변수를 find하나의 변수에 넣고 awk 명령을 다른 변수에 넣는 것입니다:

이것은 나에게 효과적인 것 같습니다 (tcsh에서):

> mkdir dir; touch dir/file
> set findopts = '-type f'
> set awkcmd = '{gsub(/.\//,"")}1'
> find . $findopts | awk "$awkcmd" 
difile

그러나 ./뒤에 슬래시가 오는 모든 문자가 일치하므로 점도 이스케이프하고 싶을 수도 있습니다.

> set awkcmd = '{gsub(/\.\//,"")}1'
> find . $findopts | awk "$awkcmd"
dir/file

또는 eval다음을 주장하는 경우 를 사용하세요.

> set cmd = 'find . -type f | awk '\''{gsub(/\.\//,"" ) }1'\'
> eval "$cmd"
dir/file

솔직히 말해서 나는 csh의 인용의 미묘함을 알지 못합니다(그리고 알아내는 데 관심도 없습니다). 위의 내용은 POSIX 계열 셸과 유사하게 작동하는 것 같지만 직접 확인해 보세요.

관련 정보