%20ihrer%20Dateinamen%20in%20einer%20Textdatei%20aufgef%C3%BChrt%20sind%3F.png)
Ich muss Hunderte von Dateien verschieben, deren Name eine ID-Nummer enthält, und diese Nummern sind zeilenweise in einer Textdatei aufgelistet.
Zum Beispiel:
The content of `ID.txt`:
1231245
1435466
3454656
3356646
Dateien, die ich verschieben muss:
1231245_134.fasta
1231245_134.dna
1435466_345.fasta
1435466_345.dna
3454656_789.fasta
3454656_789.dna
3356646_104.fasta
3356646_104.dna
Antwort1
Wie wäre es (wenn Ihre Shell „Prozesssubstitution“ bereitstellt)
. <(sed 's/^/echo mv /; s/$/* \/target/' ID.txt)
Entfernen Sie das Echo, wenn Sie mit dem Ergebnis zufrieden sind.
BEARBEITEN(vorgeschlagen von Stéphane Chazelas)
sed 's|.*|mv -- &_* /target/|' ID.txt | sh -v -n
Entfernen Sie es -n
, wenn Sie mit dem Ergebnis zufrieden sind.
Antwort2
Vorausgesetzt, die Dateinamen enthalten keine Leerzeichen, Zeilenumbrüche, Backslashes oder Anführungszeichen und Sie verfügen über eine Shell wie ksh, zsh oder bash mit Unterstützung für Prozessersetzung, können Sie Folgendes tun:
join -t_ <(printf '%s\n' *_* | sort -t_ -k1,1) <(sort ID.txt) |
xargs sh -c 'exec mv -- "$@" /target' sh
Antwort3
- Sie können
grep
das Argument-f FILE
zum Abgleichen mit Ausdrücken in angebenFILE
, eines pro Zeile. ID.txt
muss leicht geändert werden,sed
damit es nur genau mit dem übereinstimmt, was Sie möchten: ein „a“^
am Anfang jeder Zeile, damit die Zahl am Anfang einer Zeile übereinstimmt, und_
am Ende, damit „a“123
nicht übereinstimmt123123_
.ls -1
listet eine Datei pro Zeile auf.xargs -I FOOBAR
ersetzt Vorkommen von FOOBAR durch die Eingabezeile, anstatt die Eingabezeile anzuhängen.
Also:
sed -e 's/^/^/' -e 's/$/_/' /path/to/ID.txt > /tmp/ID_regexp.txt
cd /old/dir
ls -1 | grep -f /tmp/ID_regexp.txt | xargs -I FILE mv FILE /new/dir
Antwort4
Eine reine bash
Lösung:
while IFS= read -r p; do mv ${p}* /target; done < ID.txt
< ID.txt
gibt die Datei als Eingabewhile IFS= read -r p
llops durch die Linienmv ${p}* /target
Verschieben Sie alle Dateien, die mit der Nummer in der Datei beginnen, in das/target
Verzeichnis.
Um zu steuern, welche Befehle ausgeführt werden sollen, können Sie echo
vor den Befehl schreiben:mv
$ while IFS= read -r p; do echo mv ${p}* /target; done < ID.txt
mv 1231245_134.dna 1231245_134.fasta /target
mv 1435466_345.dna 1435466_345.fasta /target
mv 3454656_789.dna 3454656_789.fasta /target
mv 3356646_104.dna 3356646_104.fasta /target