2016-09-01 16 views
5

Mój skrypt:Logiczne OR w moim skrypcie

#!/bin/bash 

for file in *.ats; 
do 
    if [[ ("${file}" = THx) || ("${file}" = THy)]] 
    then cp $file /home/milenko/procmt 
    fi 
done 

Pliki w katalogu

262_V01_C00_R000_TEx_BL_128H.ats 
262_V01_C01_R000_TEy_BL_128H.ats 
262_V01_C02_R000_THx_BL_128H.ats 
262_V01_C03_R000_THy_BL_128H.ats 

Chciałem jest skopiowanie plików, które zawierają THX lub THY, ale pliki nie są kopiowane. Dlaczego?

+1

'cp * _TH [xy] _ *. Ats/home/milenk/procmt /'? Nie ma sensu mieć pętli. –

Odpowiedz

4

Co powiesz na używanie rozszerzonego globowania przy użyciu extglob? W ten sposób można wykorzystać sam for aby uzyskać wymagane rozszerzenia:

shopt -s extglob 
for file in *TH?(x|y)*.ats; do 
    # do things with "$file" ... 
done 

*TH?(x|y)*.ats rozszerza się do tych plików zawierających <something> + TH + either x or y + <something> + .ats


Twój skrypt nie działa, ponieważ masz literówkę w nim:

if [[ ("${file}" = THx) || ("${file}" = THy)]] 
#          ^
#        missing space 

To jest w porządku:

$ d="hi" 
$ [[ ($d == hi) || ($d == ha) ]] && echo "yes" 
yes 

Chociaż nawiasy są zbędne:

$ [[ $d == hi || $d == ha ]] && echo "yes" 
yes 
+1

O ile "x" i "y" nie stanowią ciągów wielokątowych, '? (X | y)' jest równoważne zwykłemu wzorowi '[xy]'. – chepner

4

Można użyć klasę postaci w glob IE *TH[xy]* aby sprawdzić, czy $file zawiera THx lub THy:

for file in *.ats; do 
    if [[ $file == *TH[xy]* ]]; then 
     cp "$file" /home/milenko/procmt 
    fi 
done 
5

Twoje pytanie określa „pliki, które zawierają THX lub Thy” ... ale kod określa, że ​​plik nazwa jest THx lub THy.

+2

Brak nazwy pliku pasującego do wzorca '* .ats' będzie oznaczać' THy' lub 'THx'. – Jdamian

9

myślę, że można uniknąć pętli w całości tutaj:

cp *TH[xy]*.ats /home/milenko/procmt 

nie ma potrzeby pętli wyników, a następnie zrobić oddzielną porównania ; pojedynczy glob rozwinie się do listy żądanych plików.

Było kilka problemów ze swoim oryginalnym podejściem:

  • Po pierwsze, próbują testować dokładnych dopasowań, więc warunek nie byłby prawdziwy.
  • Należy również uwzględnić spacje: ]] jest słowem kluczowym w komendzie złożonej [[, więc musi być oddzielnym słowem (tj. Otoczonym spacjami).
+2

Jedna uwaga: pętla jest niezbędna, jeśli oczekujesz więcej dopasowań niż mieści się w jednym wierszu poleceń. Ponadto, w wyjątkowo pedantycznej notatce, ']' jest argumentem dla polecenia * simple * [', ale' [[...]] 'jest poleceniem * compound * używającym słów kluczowych' [[i ']] '. – chepner

+0

Dzięki, zaktualizowałem treść.Czy ograniczenie długości pętli for jest większe niż w przypadku polecenia 'cp'? –

+1

W obu przypadkach wzorzec jest przekazywany do dowolnej funkcji bibliotecznej, która rozszerza wzorzec. W przypadku polecenia zewnętrznego potrzebny jest cały wynik, aby utworzyć jedną dużą listę argumentów, aby przekazać połączenie w rodzinie 'exec *'. Rozmiar tej listy argumentów podlega limitowi rozmiaru dla systemu operacyjnego. W przypadku wewnętrznego polecenia, powłoka kontroluje cały czas, więc wystarczy pobrać jeden plik na raz z wyniku, aby przetworzyć ciało. – chepner