while read -r seed name; do
sed -e "s/^seed.*/seed $seed/" \
-e "s/^output.*/output $name/" template.txt >"${name%.*}-$seed.conf"
done <file.in
Будет прочитан файл с именем file.in
. Формат этого файла должен быть
00000 filename.ext
(начальное значение в первом столбце, пробел и имя файла)
Команда sed
возьмет шаблон из template.txt
, файла, отформатированного как в вопросе, и сгенерирует новые файлы.
Новые файлы будут иметь такие имена, какfilename-00000.conf
(с использованием имени файла без расширения имени файла и исходным кодом из файла file.in
).
Выражения sed
просто ищут строки в template.txt
, которые начинаются с seed
или output
, и вставляют соответствующие значения.
$ awk 'NR==FNR{a[NR]=$0; next} {print (FNR%2 ? $0 : a[FNR])}' file1 file2
>name.A
GGG
>name.B
AAA
>name.C
TTT
>name.D
CCC
>name.E
CAT
Помимо того, что это более лаконично (и работает :-)), приведенный выше подход более эффективен, чем ваш подход, потому что:
1
)для каждой строки перед тем, как решить, печатать или нет. Также -не используйте перенаправление ввода для открытия файлов для awk, так как оно не работает для нескольких файлов (, как вы выяснили ), и лишает вас возможности проверить ИМЯ ФАЙЛА.
Ваша awk-команда в основном верна -она будет работать, если вы удалите посторонние перенаправления и поменяете порядок файлов:
$ awk 'FNR==NR {data[FNR]=$0; next} (FNR%2==1){$0=data[FNR]}1' File2 File1
>name.A
GGG
>name.B
AAA
>name.C
TTT
>name.D
CCC
>name.E
CAT
В качестве альтернативы, с GNU sed и оболочкой, поддерживающей подстановку процессов:
$ sed -e '2~2{R /dev/stdin' -e 'd}' File2 < <(sed '1~2d' File1)
>name.A
GGG
>name.B
AAA
>name.C
TTT
>name.D
CCC
>name.E
CAT
Пояснение:
sed '1~2d' File1
удалить нечетные строки из файла 1
< <(...)
передать результаты через стандартный ввод
sed -e '2~2{R /dev/stdin' -e 'd}' File2
считывать по одной строке со стандартного ввода и ставить ее в очередь для вставки после следующей четной строки File2; затем удалите четную строку
Попробуйте так, это сложно, но работает. Возможно, есть более простое решение.
Первые отдельные нечетные и четные линии:
awk '{print>"файл1 -"NR%2}" файл1 awk '{print>"файл2 -"NR%2}" файл2
Это создаст file1-0
, file1-1
, file2-0
, file2-1
В моем случае и в вашем примере файл1 -0 содержит данные, которые вам нужны из файла1, а файл2 -1 содержит данные, которые вам нужны из файла2, проверьте вывод этих файлов ниже
[mtodoric@bulletproof test]$ cat file1-0
GCCAAACAGCTAGCTTGA
GCCAAACAGCTAGCTTGATTAATAA
GCCAAACAGCTAGCTTGATTAATAATATAA
GCCAACCAGCTAGCTTAA
GCTAACCAGCTAGCTTAA
GCTGACTAGCTAGCCAACATATTT
GCCCAACAGCTAGCCCACTCA
GCCAACCAGCTAGCTTAAT
GCCAACCAGCTAGCTTAATT
[mtodoric@bulletproof test]$ cat file2-1
Siphateles.boraxobius_complete-mitochondrion_harney-county-or.fasta
Siphateles.boraxobius_complete-mitochondrion_harney-county-or.fasta
Siphateles.alvordensis_complete-mitochondrion_harney-county-or.fasta
Rhinichthys.evermanni_complete-mitochondrion_douglas-county-or.fasta
Oregonichthys.kalawatseti_complete-mitochondrion_linn-county-or.fasta
Oncorhynchus.mykiss.irideus_complete-mitochondrion_douglas-county-or.fasta
Cottus.perplexus_complete-mitochondrion_douglas-county-or.fasta
Oncorhynchus.mykiss.irideus_complete-mitochondrion_douglas-county-or.fasta
Cottus.perplexus_complete-mitochondrion_douglas-county-or.fasta
Теперь сделайте «oneliner», который объединит данные.
РБ=1; при чтении строки; выполнить эхо $line >> final.txt; sed -n ${RB}p file1 -0 >> final.txt; RB=$ ((${RB}+1 )); сделано < файл2 -1
Это в основном будет читаться из файла2 -1 (, так как в этом файле была первая строка из вашего примера вывода ), повторите каждую строку в другой файл (final.txt ), но также, благодаря переменной RB получит этот номер строки из другого файла и напечатает стандартный вывод в final.txt, а также увеличит значение RB, чтобы он мог увеличивать строку в следующем цикле.
Замените имена file2 -1 и file1 -0 в "one liner", чтобы они соответствовали вашим данным.
Надеюсь, это поможет.
Пробовал с помощью команды sed, все работает нормально
for ((i=2;i<=10;i++));do j=`sed -n ''$i'p' f1`; k=`echo $j|sed -r "s/\s+//g"`;sed -i ""$i"s/.*/"$k"/g" f2;i=$(($i+1)); done
выход
>name.A
GGG
>name.B
AAA
>name.C
TTT
>name.D
CCC
>name.E
CAT
Вы можете сделать свой pbm следующим образом, сначала вызвав утилиту paste
, чтобы расположить строки в порядке, разделенном TAB, а затем вызвать редактор sed
, чтобы выполнить операцию для получения желаемых выходных данных:
$ paste File1 File2 | sed -ne '
s/>.*\t//p
s/\t.*//p
'
Выход
>name.A
GGG
>name.B
AAA
>name.C
TTT
>name.D
CCC
>name.E
CAT
Примечание. :Posix sed не распознает \t
управляющую последовательность вместо символа табуляции. Я просто использовал его, чтобы выделить невидимый символ otw. Таким образом, вы помещаете буквальную вкладку вместо \t.
С утилитой Perl
это один -вкладыш:
$ perl -pe '$_=($_,$,.<STDIN>)[$.%2]' File1 < File2