2012-05-07 2 views
3

에서 그렙 -v 나는 떠들썩한 파티 스크립트가이ls | 내가하고 싶은 곳 스크립트

(in pseudo) 
    for each item in excludelist 
     append to string: | grep -v $item 

    for each file in directory 
    do 
     stuff 
    done 

현재 출력

ls: |: No such file or directory 
    ls: grep: No such file or directory 

모든 모든

(in real code, the creation and concatenation of f works, the problem is not here I believe) 
    for i in $EXCLUDE 
    do 
     echo $i 
     f="$f | grep -v $i" 
    done 

    for d in `ls $AWSTATSCONF/awstats*conf $f` 
    do 
     echo $d 
    done 

정말 얻을 감사 도움 이게 작동합니다.

인사말,

그림자

+0

'f = $ (echo "$ f"| grep -v "$ i")'가 더 잘 작동할까요? – VonC

+0

하지만 그 부분은 작동합니다. 문제는 ls의 실행에 있습니다. – ShadowFlame

+0

'ls' 시도가''grep' '에 접근한다고 생각하면, 그 부분이 그렇게 잘 작동한다고 생각하지 않습니다. – VonC

답변

0

당신은 $fgrep의 * 출력을 추가해야합니다. (| grep은이 현재 디렉토리에없는 물론)

$f = "$f $(grep -v $i)" 
+0

나는 내 질문을 잘못했다는 것을 믿는다. 내가 믿는 문제가있는 부분은 greps의 생성이 아니라 ls입니다. – ShadowFlame

0

문제는 일반은 ls 명령에 인수 탈출로 foo whatever whatever else이 실행될 것입니다. eval 당신은 같은 것을 할 필요가

bash는 명령과 같은 문자열을 실행하는 명령입니다

for d in `eval "ls $AWSTATSCONF/awstats*conf $f"` 
do 
    echo $d 
done 

다음 FAQ을을 확인,이 현명한 웜 보안의 큰 깡통을 여는 것을 명심 다음 다른 대안을 더 많이 이해하고

+0

문제 없습니다. 그것은 전문가에 의해서만 내부 사용을위한 것입니다. 웹 프론트 엔드 같은 것은 없습니다. 그래도 경고를 주셔서 감사합니다 :-) – ShadowFlame

0

for i in $(ls)을 사용하지 마십시오. globbing을 사용해야합니다.

grep -v의 긴 문자열을 만들기 위해 연결을 사용하지 마십시오.

$EXCLUDE은 어디에서 왔습니까? 문자열이 아닌 배열이어야합니다. 당신이 떠들썩한 파티를 사용하고 있기 때문에

for d in "$AWSTATSCONF"/awstats*conf 
do 
    for e in "${exclude[@]}" 
    do 
     if [[ $d != $e ]] 
     then 
      echo "$d" 
     fi 
    done 
done 
+0

EXCLUDE = "string1 string2 string3" – ShadowFlame

2

, 당신은 당신의 익스 클루 드 목록을 제외 할 pattern matching를 사용할 수 있습니다

pattern=$(awk ' BEGIN {OFS="|"; printf("!(")} 
       {$1=$1; printf("%s",$0)} 
       END {print ")"} 
       ' <<< $EXCLUDE) 
shopt -s extglob 
for d in $pattern; do 
    echo $d 
done  
2

가 처리하는 방법에는 여러 가지가 있습니다.

ls의 출력 구문 분석에 대한 의문점이 있습니다. 그것들의 정당성은 가능한 모든 파일 이름 (공백과 개행 문자를 포함하는 파일 이름이 특히 문제가되는 파일)을 처리해야하는지 아니면 이식 가능한 파일 이름 문자 집합을 사용하는 일반 파일 이름을 사용하는지에 따라 다릅니다 (POSIX에 따라 (라틴) 알파벳, 숫자, 플러스 ., -_).

가정 만 휴대용 파일 이름을 처리한다는 것을, 당신은 당신이 원하는 효과를 얻을 수 있습니다 : 그런 eval를 사용

for i in $EXCLUDE 
do 
    echo $i 
    f="$f | grep -v $i" 
done 

for d in `eval ls $AWSTATSCONF/awstats*conf $f` 
do 
    echo $d 
done 

가에서 파이프로 문자열 $f에 파이프를 치료하는 쉘을 강제를 껍질. 에주의하십시오 : eval는 강력하고 위험한 도구입니다.

제외 할 20 개의 용어가있는 경우 20 개의 greps를 차례로 실행하는 메커니즘은 많은 프로세스를 사용합니다. 데모 용으로 너무 심각하지는 않지만 생산 작업과 수천 개의 파일을 다루는 경우에는별로 좋지 않습니다.

당신은 아마 egrep (또는 grep -E) 명령을 구축보고 싶어

: 나는 당신이 어떤 통계가없는 가정

f="antidisestablishmentarianism" 
for i in $EXCLUDE 
do 
    f="$f|$i" 
done 

ls $AWSTATSCONF/awstats*conf | 
egrep -v "$f" | 
while read d 
do echo $d 
done 

주변에 숨어 'antidisestablishmentarianism'를 포함하는 이름 (예, 그것의와 파일 실제 단어, 그것은 농담으로 주로 사용되지만).

while read 공식은 for 루프를 작성하는 또 다른 방법입니다. 부모 프로세스의 변수에 영향을 줄 수없는 하위 프로세스를 조심하십시오. 즉, while 루프는 주 쉘이 아닌 하위 쉘로 처리되므로 주 쉘에서 변수를 설정하기 위해 루프를 사용하는 경우에는 —이 작동하지 않고 다시 돌아갈 수 있습니다. for 루프. 그러나, 당신은 다시 eval 필요하지 않습니다 :

for d in $(ls $AWSTATSCONF/awstat*conf | egrep -v "$f") 
do 
    echo $d 
done 

일반적으로 좋은 생각이 다시 따옴표 대신 $(...) 사용.

관련 문제