2016-07-25 23 views
0
#!/bin/bash 
for filenames in $(ls $1) 
do 
    echo $filenames | grep "\.old$" 
    if [ ! $filenames = 0 ] 
    then 
    $(mv "$1/$filenames" "$1/$filenames.old") 
    fi 
done 

Also ich denke das meiste Skript funktioniert. Es ist beabsichtigt, die Ausgabe von ls für ein Verzeichnis zu übernehmen, das im ersten Parameter eingegeben wurde, und am Ende nach Dateien mit .old zu suchen. Alle Dateien, die nicht .old enthalten, werden umbenannt. Das Skript benennt die Dateien erfolgreich um, fügt jedoch eine Datei zu einer Datei hinzu, die bereits die Erweiterung enthält. Ich gehe davon aus, dass die If-Variable falsch ist, aber ich kann nicht herausfinden, welche Variable in diesem Fall verwendet werden soll.Fügen Sie .old zu Dateien ohne .old hinzu, die Probleme mit der zu verwendenden Variablen haben?

Antwort ist in dem Schlüssel, aber wenn jemand dies hier tun muß, ist eine noch einfachere Art und Weise:

#!/bin/bash 
for filenames in $(ls $1 | grep -v "\.old$") 
do 
    $(mv "$1/$filenames" "$1/$filenames.old") 
done 
+1

Sie dies nicht tun brauche das '$ (...)', das deinen 'mv' cmd umgibt. Viel Glück. – shellter

Antwort

3

Verwenden `findet für diese

find /directory/here -type f ! -iname "*.old" -exec mv {} {}.old \; 

Probleme des ursprünglichen Ansatz

  • for filenames in $(ls $1) Nie parsen ls Ausgabe. Überprüfen Sie [ this ]
  • Variablen sind nicht doppelt zitiert, sagen in if [ ! $filenames = 0 ]. Dies führt zu einer Worttrennung. Verwenden Sie "$filenames", sofern Sie keine Worttrennung erwarten.

So würde das endgültige Skript

#!/bin/bash 
if [ -d "$1" ] 
then 
find "$1" -type f ! -iname "*.old" -exec mv {} {}.old \; 
# use -maxdepth 1 with find if you don't wish to recursively check subdirectories 
else 
echo "Directory : $1 doesn't exist !" 
fi 

Nutzungs

./script '/path/to/directory' 
+0

Danke, aber es muss nicht so komplex sein. Ich musste einfach das Skript sagen "Wenn die Ausgabe von Grep nicht wahr ist, dann benenne die Datei um, damit sie wahr wird". –

+2

@ KieranO'Connor: Verwenden Sie 'Grep' oder' ls' wie Ihr Beispiel ist ein Rezept für eine Katastrophe; Verwenden Sie stattdessen eine Glob- oder For-Schleife. Zu viele schlechte Dinge können beginnen, wenn Sie unnötige Dinge tun. –

+1

'find' wird auch Unterverzeichnisse aufsuchen (es sei denn, Sie lassen es explizit aus), was für diese Aufgabe wahrscheinlich falsch ist. – tripleee

-3

ich das Problem gelöst, wie ich von meinem Lehrer die Irre geführt wurde! $? ist die Variable, die die Pipeline-Ausgabe repräsentiert, die momentan im Vordergrund liegt (was grep wäre). Der neue Code ist außer Unedited für

if [ ! $? = 0 ] 
+0

Verwenden Sie '-eq' für den Ganzzahlvergleich. – sjsam

+0

Ich kenne -eq, aber ich denke, dass meine Schulmatrix entweder = oder -eq verwendet. –

+1

versuchen Sie 'Echo' $? jetzt = '$? ; wahr ; echo '$? =' $? ; falsch; echo '$? =' $? ; wahr ; echo '$? =' $? '. Sie sollten 0,0,1,0 (in separaten Zeilen) sehen. Dies ist der Rückgabecode des vorherigen Befehls, der ausgeführt wurde, nicht "die Variable, die die Pipelineausgabe darstellt, die sich gerade im Vordergrund befindet". Viel Glück – shellter

1

Sie wollen telefonieren vermeiden zusätzlichen Dienstprogramm Funktionen, wenn einfach Shell builtins tun. Warum? Jedes zusätzliche Dienstprogramm, das Sie aufrufen, grep usw., erzeugt und läuft in einer eigenen eigenen Subshell. (Wenn Sie eine Subshell für jede Iteration in Ihrer Schleife spawnen - Dinge werden wirklich langsamer) Wenn die Shell keine Funktion zur Verfügung stellt, dann sicher ... ein Dienstprogramm aufrufen ist das Richtige zu tun.

Wie oben erwähnt, Globbing Schale mit Parametern Ausdehnung entlang mit Teilzeichenfolge Entfernung stellt einen einfachen Test zur Bestimmung, ob eine Datei eine .old Erweiterung hat. Sie brauchen, ist:

for i in "$1"/*; do 
    [ "${i##*.}" = "old" ] || mv "$i" "${i}.old" 
done 

(Anmerkung: dies die .old Erweiterung einzelne Datei überspringen hinzufügen 'old' genannt, aber das separat bei Bedarf bearbeitet werden können - unwahrscheinlich.Darüber hinaus ist die Lösung mit find ein feiner Ansatz auch)

+1

Ich denke du willst 'mv' statt' move'. – tripleee

+0

Yup, Phonetik ... –

2

Don't use ls in scripts.

#!/bin/bash 
for filename in "$1"/* 
do 
    case $filename in *.old) continue;; esac 
    mv "$filename" "$filename.old" 
done 

I case über if bevorzugen, weil es Wildcard natürlich und portabel passende unterstützt. (Sie dies mit /bin/sh laufen könnte genauso gut.) Wenn Sie wollten stattdessen if verwenden, würde das

if echo "$filename" | grep -q '\.old$'; then 

oder mehr idiomatisch sein, aber die jüngsten Muscheln nur,

if [[ "$filename" == *.old ]]; then 
+1

@ l'L Danke; Fest. – tripleee

+0

Danke, es funktioniert, aber meine Hausaufgabe erforderte, dass ich ls in der for-Schleife verwendete. Ich habe mehr darüber recherchiert, warum Sie es nicht benutzen wollen, und ich stimme in 99% der Fälle zu. Meine Shell gibt nur Dateinamen aus, und nur 1 pro Zeile, wenn kein Argument -l vorhanden ist. Daher gibt es kein Problem bei der Verwendung dieses Skripts in einem Unterverzeichnis, das nur Dateien oder Verzeichnisse enthält, die Sie nicht mehr verwenden. –

+0

Es gibt * eine 'for' Schleife. Das erste Problem mit 'ls' besteht darin, dass die Shell, wenn ihre Ausgabe ein Leerzeichen enthält, sie in zwei Token teilt, wie' die: Datei nicht gefunden' und 'Datei: Datei nicht gefunden'. Das nächste Problem ist, dass, wenn es benachbarte Leerzeichen gibt, die Shell sie im Grunde ignorieren wird, als ob es nur eins gäbe. Und natürlich ist der [nutzlose Gebrauch von 'ls'] (http://www.iki.fi/era/unix/award.html) einfach verschwenderisch. Wenn Ihr Dozent darauf besteht, einen externen Subprozess zu verwenden, wo keiner notwendig ist, sind sie inkompetent, und Sie können sie gerne bitten, sich hier zu registrieren, um weiter zu diskutieren. – tripleee