2016-07-19 14 views
2

Ich bin neu zu schreiben Bash und ich bin mir sicher, dass ich das auf die harte Tour, also wenn jemand kann mir helfen, meinen Code zu reduzieren oder sagen Sie mir, was falsch ist, wäre fantastisch.Schleife durch Unterverzeichnisse explodierenden Dateinamen mit Bash

Ich versuche, durch ein Hauptverzeichnis sowie Unterverzeichnisse zu finden, Dateinamen zu finden und sie zu explodieren, damit ich Teile aus den Dateinamen herausziehen kann.

Meine Verzeichnisstruktur geht so, das ist nur ein Beispiel. Die Ordner wie „0000“ variieren

/images/0000/somefilename1_this.jpg 
/images/1111/somefilename2_this.jpg 
/images/2222/somefilename3_this.jpg 
/images/3333/somefilename4_this.jpg 

Mein Skript funktioniert gut, bis ich zu FINALIFS='_' read -ra FINALNAME <<< "$FINALSTR"; bekommen, wo ich versuche, die Dateinamen durch einen Unterstrich zu explodieren und es in einem Array zu erhalten. Wenn ich echo ${FINALNAME[0]}; es ist leer. Auf der letzten for done bekomme ich einen synax-Fehler, wenn ich letztens for done auskommentiere bekomme ich nicht mehr den Syntaxfehler.

Mein ultimatives Ziel ist es, einen Teil der Dateinamen und deren aktuelles Verzeichnis in Variablen zu bekommen, damit ich später etwas machen kann.

0000 somefilename1 
1111 somefilename2 
2222 somefilename3 
3333 somefilename4 

Jede Hilfe wäre willkommen.

for d in */ ; do 
    for file in "$d"*.jpg ; do 
     STR="$file"; 
     IFS='/' read -ra SPLITNAMES <<< "$STR"; 
     for i in "${SPLITNAMES[1]}"; do 
     FINALSTR="$i"; 
     FINALIFS='_' read -ra FINALNAME <<< "$FINALSTR"; 
     echo ${FINALNAME[0]}; <-- this is empty 
     for b in "${FINALNAME[0]}"; do 

     done <-- I get a syntax error here 
     done 
     # mkdir /images/$d$(date '+%Y-%m-%d'); 
     # mv /images/$d$(date '+%Y-%m-%d')_* /images/$d$(date '+%Y-%m-%d'); 
    done 
done 
+0

'echo $ FILE | geschnitten -d/-f3- | Schnitt -d_ -f1 | tr '/' '' ' –

+0

In' um einen Teil der Dateinamen zu erhalten' Gibt es einen konstanten Teil, der am Ende jedes Dateinamens weggelassen werden soll. Bitte aktualisieren Sie die erwartete Ausgabe in diesem Fall – sjsam

+0

'IFS' ist eine Variable, nach der' read' in ihrer Umgebung sucht; 'FINALIFS' ist nicht. – chepner

Antwort

2

Sie Ihr Skript mit einem find vereinfachen und dann teilen Sie es unterstreichen und Schrägstrich mit einem read:

while IFS= read -r -d '' file; do 
    IFS='_/' read -ra arr <<< "$file" 
    echo "${arr[2]} ${arr[3]}" 
done < <(find ./images -type f -print0) 

0000 somefilename1 
1111 somefilename2 
2222 somefilename3 
3333 somefilename4 
+0

gibt es eine Möglichkeit, nur Dateien, die enden mit '.jpg' und' .html'? –

+0

Ja mit 'find' können Sie tun: **' während IFS = read -r -d '' Datei; tue IFS = '_ /' read -ra arr <<< "$ file"; echo "$ {arr [2]} $ {arr [3]}"; done <<(find ./images -type f \ (-name '* .jpg' -o -name '* .html' \) -print0) '** – anubhava

+1

Du bist der Mann, vielen Dank, dass es getan hat und reduziert den Mist aus meinem Code :) –

0

find würde die Arbeit machen

#!/bin/bash 
if [ ! -d "$1" ] # Checking if the directory entered as argument1 exists 
then 
echo " $1 Not a valid directory" 
exit 1 
fi 
filename_processor() # This is a bash function 
{ 
temp1=${@##*/} 
temp2=${@%/*} 
echo "${temp2##*/} ${temp1%%_*}" 
} 
export -f filename_processor 
find "$1" -type f -name "*.jpg" -name ".html" \ 
    -exec bash -c 'filename_processor "$1"' _ {} \; 

Referenzen

  1. finden [ manpage ].
  2. Shell-Parameter [ expansion ].
Verwandte Themen