![Как заменить часть имени файла данными из stdin?](https://rvso.com/image/178489/%D0%9A%D0%B0%D0%BA%20%D0%B7%D0%B0%D0%BC%D0%B5%D0%BD%D0%B8%D1%82%D1%8C%20%D1%87%D0%B0%D1%81%D1%82%D1%8C%20%D0%B8%D0%BC%D0%B5%D0%BD%D0%B8%20%D1%84%D0%B0%D0%B9%D0%BB%D0%B0%20%D0%B4%D0%B0%D0%BD%D0%BD%D1%8B%D0%BC%D0%B8%20%D0%B8%D0%B7%20stdin%3F.png)
Допустим, у меня есть файл ids.txt
с несколькими записями, например
foo
bar
bam
...
например. Я хотел бы использовать это как входные данные для запуска команды для некоторых файлов, содержащих идентификаторы в имени файла, например foo_1.gz
, foo_2.gz
, bar_1.gz
, bar_2.gz
, , ... и так далее.
Я попытался сослаться на ввод с помощью, {}
как я видел, это работает с другой командой, вот так:
cat ids.txt | xargs my.command --input1 {}_1.gz --input2 {}_2.gz
но он всегда выдает мне эту ошибку:
{}_1.gz no such file or directory
Есть ли способ обрабатывать входные данные cat
как строки символов и автоматически вставлять их в имена входных файлов для my.command
?
Проблема также в том, что my.command
каждый раз требуются два входных файла, поэтому я не могу просто использовать список с реальными именами файлов вместо ids.txt
.
решение1
Вам необходимо использовать -I
опцию здесь:
$ 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
В качестве альтернативы можно использовать цикл оболочки:
while read id; do
my.command --input1 "${id}"_1.gz --input2 "${id}"_2.gz
done < ids.txt
Это предполагает, что ваши идентификаторы не содержат пробелов или обратных косых черт. Если они есть, используйте это:
while IFS= read -r id; do
my.command --input1 "${id}"_1.gz --input2 "${id}"_2.gz
done < ids.txt
Наконец, вы также можете использовать список с двумя именами файлов в каждой строке:
$ cat ids.txt
foo_1.gz foo_2.gz
bar_1.gz bar_2.gz
bam_1.gz bam_2.gz
Сейчас:
while read file1 file2; do
my.command --input1 "$file1" --input2 "$file2"
done < ids.txt