«Правильный» инструмент для запуска команды в серии строк из стандартного ввода (или где-либо еще )— этоxargs
:
grep error log.txt | xargs -r -d\\n -n 1 bash -c 'echo ${0:20:10}'
Однако в вашем примере действительно лучше использоватьcut
:
grep error log.txt | cut -c21-30
Один из способов — использовать цикл, заменяя пробелы по одному, пока перед первым двоеточием не останется пробелов:
$ sed -e :a -e '/[^:]* [^:]*:/s/ /_/;ta' input.txt
[Candidatus_Protochlamydia_amoebophila_UWE25: NC_005861]
MNQRTGILLVNLGTPKTPRPKDVYRYLNEFLTDGRVIDLPWLKRQLLVRC
IIVPFRYKQSSMLYQKLWTAEGSPLLVHGIAVQTKLQMILGESFQVELAM
[Gluconobacter_oxydans_621H: NC_006677]
MAFLHKTPRIAPPPEGRTGILLINLGTPDDTGYFSVRRYLSEFLSDRRVI
ESPPLIWQPILQSIILTKRPFASGANYARIWHKEENASPLRVYTRRQAEG
Более подход KISS может заключаться в замене всех пробелов -, а затем повторной -замене пробела после двоеточия:
sed -e 's/\s\+/_/g' -e 's/:_/: /' input.txt
Если Perl является опцией, вы можете использовать отрицательный просмотр назад для замены только тех экземпляров, которым не предшествует двоеточие:
perl -pe 's/(?<!:) /_/g' input.txt