2017-12-22 9 views
2

Ich habe eine Liste von *.new Dateien in einem Verzeichnis. Diese Datei enthält D1 in ihrem Namen, die zu D2 ersetzt werden soll, und auch von .new zu nichts, um die Erweiterung zu entfernenMehrere Dateien umbenennen Ändern der Erweiterung und Teil der Zeichenfolge

hello_world_D1_122.txt.new -------> hello_world_D2_122.txt 

Was habe ich versuchte, ist

ls -slt | grep -iE "*.new$" | awk -F " " '{print $10}' | xargs -I {} mv {} "echo {} | sed -e 's/.D1./.D2./g ; s/.new//g'" 

Dieser Befehl wird nicht die Herstellung von erforderliche Ausgabe. Ausgabe des obigen Befehl ist

mv: rename hello_world_D1_122.txt.new to echo hello_world_D1_122.txt.new | sed -e 's/D1/D2/g ; s/.new//g': No such file or directory 
+0

Was ist zu tun? Geben Sie eine Beispielausgabe des Problems an. – Nic3500

+0

Dieser Befehl soll alle Dateinamen in die gewünschten konvertieren. Bsp .: hallo_world_D1_122.txt.new -------> hallo_world_D2_122.txt –

+0

Deh! OK. Ich meinte, was macht dein jetziges Kommando? – Nic3500

Antwort

1

Ihren aktuellen Versuchs enthält eine große Anzahl von Problemen zusätzlich zu den offensichtlichen Syntaxfehlern.

Das Argument "echo {} | sed '...'" ist eine Literalzeichenfolge; Es gibt keine Möglichkeit xargs könnte dies als ein Befehl interpretieren (obwohl es natürlich ersetzen {} mit dem Dateinamen innerhalb dieser Zeichenfolge).

Zusätzlich, don't use ls in scripts und wenn Sie wirklich müssen, mit ls -l und dann wegwerfen das lange Format ist ... nur albern, sowie ineffizient und fehleranfällig (siehe den Link für Details).

Offensichtliche und überlegene Art und Weise, dies zu lösen ist, ohne xargs:

for f in ./*.new; do 
    [ -f "$f" ] || continue # in case the glob matches no files 
    d=${f%.new}    # trim off extension 
    mv "$f" "${d/.D1./.D2.}" # replace .D1. with .D2. 
done 

(ich denke, Sie wörtliche Punkte ersetzen möchten, wenn Ihre Regex jedes Zeichen außer Newline von D1 beliebiges Zeichen folgt, gefolgt entsprechen würde, außer . newline)

Wenn Sie auf eine xargs Lösung bestehen, können Sie das Skript in bash -c '...' wickeln und zu xargs passieren:

printf '%s\0' ./*.new | xargs -r0 bash -c 'for f; do d=${f%.new}; mv "$f" "${d/.D1./.D2.}"; done' _ 
+0

Auf dieser Seite gibt es auch eine Reihe von Fragen darüber, wie man die verschiedenen "rename" -Befehle benutzt, von denen einige dies leicht tun können, die die Anzahl der Atome im bekannten Universum noch nicht übertreffen. – tripleee

+0

Sieht mehr oder weniger ähnlich zu meinen (nicht behaupten Plagiieren obwohl) '++' – Inian

+0

Ja, nur sah Ihr Update - Ich würde dies löschen, wenn ich nicht von Kommentaren auf die andere Antwort verweisen. – tripleee

4

Warum die ganze Runde über Möglichkeiten, eine Reihe von Shell-Tools können Sie die verschiedenen bash Tool eingebaut Ins für diese verwenden können, Parameter-Erweiterung Syntax für String-Manipulation mit

for file in *.new; do 
    [ -f "$file" ] || continue 
    temp="${file%*.new}" 
    mv -- "${file}" "${temp/D1/D2}" 
done 

der Teil "${file%*.new}" Streifen der Erweiterung .new aus dem Dateinamen und "${temp/D1/D2}"D1 mit D2

ersetzt ich habe keine Ahnung, warum die Ausdauer zu verwenden GNU xargs, aber Sie können diese nicht lesbare Möglichkeit verwenden, um das zu erreichen. printf Verwendung der Dateien mit null abgrenzen auflisten und verwenden xargs -0 mit null als abgrenzen Zeichen zu lesen,

printf '%s\0' *.new | xargs -0 -r -I {} sh -c 'temp="${0%*.new}"; mv -- "${0}" "${temp/D1/D2}"' {} 
+0

danke für die Antwort ..really schätzen es –

+0

'$ {var/pattern/replacement}' ist nicht richtig portierbar zu 'sh'. – tripleee

+0

@tripleee: Wirklich? interessant! Wird es in den offiziellen Dokumenten erwähnt? – Inian

1

Mit GNU paralllel es sieht wie folgt aus:

parallel mv {} '{=s/D1/D2/;s/.new//=}' ::: *.new 

Wenn Sie verrückt Dateinamen haben:

touch "$(printf "Shell Special\n\n'*$!_D1_txt.new")" 
parallel -0 mv {} '{=s/D1/D2/;s/.new//=}' ::: *.new 
Verwandte Themen