![Wie ersetze ich einen Teil eines Dateinamens durch eine Eingabe von stdin?](https://rvso.com/image/178489/Wie%20ersetze%20ich%20einen%20Teil%20eines%20Dateinamens%20durch%20eine%20Eingabe%20von%20stdin%3F.png)
Nehmen wir an, ich habe eine Datei ids.txt
mit 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 cat
als Zeichenfolgen zu behandeln und sie automatisch in die Eingabedateinamen für einzufügen my.command
?
Das Problem besteht auch darin, dass my.command
jedes 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 -I
Option 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