#unix #sed
Вопрос:
Надеюсь, кто-нибудь добрый сможет мне помочь, пожалуйста!
У меня есть файл input.list
:
/scratch/user/IFS/IFS001/IFS003.GATK.recal.bam
/scratch/user/IFS/IFS002/IFS002.GATK.recal.bam
/scratch/user/EGS/ZFXHG22/ZFXHG22.GATK.recal.bam
и я хочу извлечь бит раньше .GATK.recal.bam
— я нашел решение для этого:
sed 's/.GATK.recal.bam.*//' input.list | sed 's@.*/@@'
Теперь я хочу включить это в цикл while, но это не работает… пожалуйста, может кто-нибудь взглянуть и указать мне, где я делаю что-то не так. Моя попытка приведена ниже:
while read -r line; do ID=${sed 's/.GATK.recal.bam.*//' $line | sed 's@.*/@@'}; sbatch script.sh $ID; done < input.list
Приносим извинения за легкую Q…
Комментарии:
1.
$line
это не файл.$()
Не используйте${}
. Цитируйте использование переменных:"$line"
,"$ID"
, и т.д. Вы также можете использовать один sed без использования while:<input.list sed -e 's/.GATK.recal.bam.*//' -e 's@.*/@@' | xargs -I@ sbatch script.sh @
Ответ №1:
Вы можете использовать выходные sed
данные команды в качестве входных данных для цикла:
sed 'COMMAND' input.file | while read -r id ; do
some_command "${id}"
done
Вместо петли также xargs
можно использовать:
sed 'COMMAND' input.file | xargs -n1 some_command
ps: GNU sed поддерживает выполнение результата s
операции в виде команды. Я бы не рекомендовал использовать это в производстве, по крайней мере, по соображениям переносимости, но, вероятно, об этом стоит упомянуть:
sed 's/(.*).GATK.recal.bam.*/sbatch script.sh 1/e' input.file
Ответ №2:
Вы можете сделать это прямо bash
(если вы используете эту оболочку; ksh93
и zsh
будет очень похоже), не sed
требуется:
while read -r line; do
id="${line##*/}" # Remove everything up to the last / in the string
id="${id%.GATK.recal.bam}" # Remove the trailing suffix
sbatch script.sh "$id"
done < input.list
По крайней мере, вы можете использовать один sed
звонок на линию:
id=$(sed -e 's/.GATK.recal.bam$//' -e 's@.*/@@' <<<"$line")
или с простым sh
id=$(printf "%sn" "$line" | sed -e 's/.GATK.recal.bam$//' -e 's@.*/@@')