Come sostituire una stringa con l'output di un comando

Ecco come sostituire una stringa di un file di testo con l’output di un comando in bash.

A cura di Dennis Angemi  | issue #247 | guida/e Andrea Borruso


Use case

Se hai un file markdown (sia esso metadata.md) così fatto:

## 👥 Contributors
{{{contributors}}}

e vuoi sostituire la stringa “{{{contributors}}}” con l’output multiline di un comando in bash, puoi usare perl in questo modo:

perl -i -p -e 's/{{{contributors}}}/'"$(comando)"'/g' metadata.md

Esempio

Se l’output multiline a cui siamo interessati si ottiene con il comando

cat datapackage.yaml | yq '[.contributors[] | {Name: .title, Role: .role, Email: .email}]' | mlr --j2m cat

che produce

| Name | Role | Email |
| --- | --- | --- |
| Tizio | author | tizio@test.it |
| Caio | maintainer | caio@test.it |

possiamo salvarlo in una variabile e usare perl come indicato sopra

#!/bin/bash

out=$(cat datapackage.yaml | yq '[.contributors[] | {Name: .title, Role: .role, Email: .email}]' | mlr --j2m cat)

perl -i -p -e 's/{{{contributors}}}/'"$out"'/g' metadata.md

Nel mio caso, si ottiene una cosa del tipo

## 👥 Contributors
| Name | Role | Email |
| --- | --- | --- |
| Tizio | author | tizio@test.it |
| Caio | maintainer | caio@test.it |

Soluzione alternativa

Puoi anche utilizzare sed creando un file temporaneo

<datapackage.yaml yq '[.contributors[] | {Name: .title, Role: .role, Email: .email}]' | mlr --j2m cat >temp.txt

sed -i -e '/{{{contributors}}}/r temp.txt' -e '//d' metadata.md

# if file exists, delete it
if [ -f temp.txt ]; then
    rm temp.txt
fi
Ultima modifica 15/02/2023: update ricetta (a0de46e)