Wie ersetze ich einen Teil eines Dateinamens durch eine Eingabe von stdin?

Wie ersetze ich einen Teil eines Dateinamens durch eine Eingabe von stdin?

Nehmen wir an, ich habe eine Datei ids.txtmit mehreren Einträgen wie

foo
bar
bam
...

zum Beispiel. Ich möchte dies als Eingabe verwenden, um einen Befehl für einige Dateien auszuführen, die die IDs im Dateinamen enthalten, wie foo_1.gz, foo_2.gz, bar_1.gz, bar_2.gz, ... und so weiter.

Ich habe versucht, auf die Eingabe zu verweisen, {}da ich gesehen habe, dass dies mit einem anderen Befehl funktioniert, und zwar etwa so:

cat ids.txt | xargs my.command --input1 {}_1.gz --input2 {}_2.gz 

aber ich bekomme immer diesen Fehler:

{}_1.gz no such file or directory

Gibt es eine Möglichkeit, die Eingabe von catals Zeichenfolgen zu behandeln und sie automatisch in die Eingabedateinamen für einzufügen my.command?

Das Problem besteht auch darin, dass my.commandjedes Mal zwei Eingabedateien erforderlich sind, sodass ich nicht einfach eine Liste mit den tatsächlichen Dateinamen anstelle der verwenden kann ids.txt.

Antwort1

Sie müssen die -IOption hier verwenden:

$ cat ids.txt | xargs -I{} echo my.command --input1 {}_1.gz --input2 {}_2.gz 
my.command --input1 foo_1.gz --input2 foo_2.gz
my.command --input1 bar_1.gz --input2 bar_2.gz
my.command --input1 bam_1.gz --input2 bam_2.gz

Alternativ können Sie eine Shell-Schleife verwenden:

while read id; do 
    my.command --input1 "${id}"_1.gz --input2 "${id}"_2.gz
done < ids.txt

Das setzt voraus, dass Ihre IDs keine Leerzeichen oder Backslashes enthalten. Wenn doch, verwenden Sie stattdessen Folgendes:

while IFS= read -r id; do 
    my.command --input1 "${id}"_1.gz --input2 "${id}"_2.gz
done < ids.txt

Schließlich könnten Sie auch eine Liste mit zwei Dateinamen pro Zeile verwenden:

$ cat ids.txt
foo_1.gz foo_2.gz
bar_1.gz bar_2.gz
bam_1.gz bam_2.gz

Jetzt:

while read file1 file2; do
    my.command --input1 "$file1" --input2 "$file2"
done < ids.txt

verwandte Informationen