Wie kann ich Hunderte von Dateien verschieben, deren Schlüsselwort (ID) ihrer Dateinamen in einer Textdatei aufgeführt sind?

Wie kann ich Hunderte von Dateien verschieben, deren Schlüsselwort (ID) ihrer Dateinamen in einer Textdatei aufgeführt sind?

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 grepdas Argument -f FILEzum Abgleichen mit Ausdrücken in angeben FILE, eines pro Zeile.
  • ID.txtmuss leicht geändert werden, seddamit 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“ 123nicht übereinstimmt 123123_.
  • ls -1listet eine Datei pro Zeile auf.
  • xargs -I FOOBARersetzt 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 bashLösung:

while IFS= read -r p; do mv ${p}* /target; done < ID.txt
  • < ID.txtgibt die Datei als Eingabe
  • while IFS= read -r pllops durch die Linien
    • mv ${p}* /targetVerschieben Sie alle Dateien, die mit der Nummer in der Datei beginnen, in das /targetVerzeichnis.

Um zu steuern, welche Befehle ausgeführt werden sollen, können Sie echovor 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

verwandte Informationen