2016-09-01 2 views
5

Mein Skript:Logical OR in meinem Shell-Skript

#!/bin/bash 

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

Dateien im Verzeichnis

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 

Was ich wollte, ist, die Dateien zu kopieren, die THx oder THY enthalten, aber die Dateien werden nicht kopiert. Warum?

+1

'cp * _TH [xy] _ *. Ats/home/milenk/procmt /'? Es hat keinen Sinn, eine Schleife zu haben. –

Antwort

4

Was extglob für längeren Globbing mit? Auf diese Weise können die Verwendung for selbst die erforderlichen Erweiterungen zu erhalten:

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

*TH?(x|y)*.ats auf diese Dateien erweitert <something> + TH + either x or y + <something> + .ats


Ihr Skript enthält schlägt fehl, weil Sie einen Tippfehler drin haben:

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

Das ist in Ordnung:

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

Obwohl die Klammern sind überflüssig:

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

Es sei denn, 'X' und 'Y' multi Strings repräsentieren ist, '? (X | y)' entspricht das gewöhnliche Muster '[xy]'. – chepner

4

Sie können Zeichenklasse in glob dh *TH[xy]* verwenden zu überprüfen, ob $file enthält THx oder THy:

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

Ihre Frage „Dateien, die THx oder THY enthalten“ gibt ... aber Ihr Code gibt an, dass die Datei Name ist THx oder THY.

+2

Kein Dateiname, der mit dem Muster '* .ats' übereinstimmt, ist' THy' und 'THx'. – Jdamian

9

Ich glaube, Sie ganz hier eine Schleife vermeiden:

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

Es gibt keine Notwendigkeit, eine Schleife durch die Ergebnisse und dann über einen separaten Vergleich zu tun ; Ein einzelner Glob wird auf die Liste der gewünschten Dateien erweitert.

Es gab ein paar Probleme mit Ihrem ursprünglichen Ansatz:

  • Erstens Sie versuchen, um nach Übereinstimmungen zu testen, so wäre die Bedingung nie wahr sein. Auch
  • , kümmern mit Leerzeichen: ]] ist ein Schlüsselwort in der Verbindung Befehl [[, so braucht es ein getrenntes Wort zu sein (das heißt durch Leerzeichen umgeben).
+2

Ein Vorbehalt: Die Schleife ist erforderlich, wenn Sie mehr Übereinstimmungen erwarten, als auf eine Befehlszeile passen. Auch auf einem extrem pedantisch Note, ']' ist ein Argument für den * einfachen * Befehl '[', aber '[[...]]' ist eine * Verbindung * Befehl Schlüsselwörter '[[' und ']] '. – chepner

+0

Danke, ich habe den Wortlaut aktualisiert.Ist also die Längengrenze der 'for' -Schleife größer als beim' cp'-Befehl? –

+1

In beiden Fällen wird das Muster an die Bibliothek übergeben, die das Muster erweitert. Für einen externen Befehl benötigen Sie das gesamte Ergebnis, um eine große Argumentliste zu erstellen, die an einen Aufruf in der 'exec *' - Familie übergeben wird. Die Größe dieser Argumentliste unterliegt einer OS-spezifischen Größenbeschränkung. Bei einem internen Befehl hat die Shell die ganze Zeit die Kontrolle, so dass sie nur eine Datei aus dem Ergebnis abrufen muss, um den Körper zu verarbeiten. – chepner

Verwandte Themen