[RISOLTO] Creare ex novo un file di testo di n righe in uno script

Postate qui per tutte le discussioni legate a Linux in generale.

Moderatore: Staff

Regole del forum
1) Citare sempre la versione di Slackware usata, la versione del Kernel e magari anche la versione della libreria coinvolta. Questi dati aiutano le persone che possono rispondere.
2) Per evitare confusione prego inserire in questo forum solo topic che riguardano appunto Gnu/Linux in genere, se l'argomento è specifico alla Slackware usate uno dei forum Slackware o Slackware64.
3) Leggere attentamente le risposte ricevute
4) Scrivere i messaggi con il colore di default, evitare altri colori.
5) Scrivere in Italiano o in Inglese, se possibile grammaticalmente corretto, evitate stili di scrittura poco chiari, quindi nessuna abbreviazione tipo telegramma o scrittura stile SMS o CHAT.
6) Appena registrati è consigliato presentarsi nel forum dedicato.

La non osservanza delle regole porta a provvedimenti di vari tipo da parte dello staff, in particolare la non osservanza della regola 5 porta alla cancellazione del post e alla segnalazione dell'utente. In caso di recidività l'utente rischia il ban temporaneo.
Rispondi
gian_d
Linux 3.x
Linux 3.x
Messaggi: 654
Iscritto il: mer 16 lug 2014, 17:35
Nome Cognome: Giancarlo Dessì
Slackware: 64 current
Kernel: 6.6.xx
Desktop: KDE 5.27
Località: Sardinia
Contatta:

[RISOLTO] Creare ex novo un file di testo di n righe in uno script

Messaggio da gian_d »

Scusate l'ignoranza, ma mi sto sbattendo con una stupidaggine, ovvero quella di creare all'interno di uno script bash (uno slackbuild) un file di testo.
Ad esempio, devo creare un file di testo con il seguente contenuto:

Codice: Seleziona tutto

Riga 1
Riga 2
Riga 3

compresa una riga vuota alla fine.

Ho provato con cat ma non c'è verso: o inserisco dei file oppure mi chiede un input.
Ho provato a inserire l'intero testo all'interno dello script come input ma evidentemente non riconosce la sequenza di escape \n per la nuova riga.
In altri termini,

Codice: Seleziona tutto

cat "Riga 1\nRiga 2\nRiga 3\n\n" > nomefile
Inserisce in nomefile l'intero testo ma formattato in una sola riga con incluse le stringhe "\n" come tali

Ho fatto anche dei tentativi con echo e con le pipeline ma non ne cavo piede.

Come posso fare?
Ultima modifica di gian_d il ven 8 apr 2022, 8:01, modificato 1 volta in totale.

gian_d
Linux 3.x
Linux 3.x
Messaggi: 654
Iscritto il: mer 16 lug 2014, 17:35
Nome Cognome: Giancarlo Dessì
Slackware: 64 current
Kernel: 6.6.xx
Desktop: KDE 5.27
Località: Sardinia
Contatta:

Re: Creare ex novo un file di testo di n righe in uno script

Messaggio da gian_d »

L'unica alternativa che mi viene in mente è quella di una patch che crea dei nuovi file all'interno di un tarball scompattato, ma ci sarebbe poi il problema di passare a questa patch una variabile d'ambiente.

Una soluzione forse potrebbe essere sed, ma non sono mai riuscito ad usare questo comando se non copiando dei modelli semplici adatti all'occorrenza.

Avatar utente
targzeta
Iper Master
Iper Master
Messaggi: 6629
Iscritto il: gio 3 nov 2005, 14:05
Nome Cognome: Emanuele Tomasi
Slackware: 64-current
Kernel: latest stable
Desktop: IceWM
Località: Carpignano Sal. (LE) <-> Pisa

Re: Creare ex novo un file di testo di n righe in uno script

Messaggio da targzeta »

Se non ho capito male, quello che cerchi si chiama here-document, ed è documentato nel manuale della bash. Qui un esempio:

Codice: Seleziona tutto

cat <<EOF > /tmp/casa.txt
Ciao mamma,
guarda come mi diverto

EOF
Se lo esegui crea un file chiamato /tmp/casa.txt con il testo che leggi. Alternativamente hai anche il comando "echo -e":

Codice: Seleziona tutto

echo -e "Ciao mamma,\nguarda come mi diverto\n" > /tmp/casa.txt
Dipende da te quale usare,
Emanuele
Se pensi di essere troppo piccolo per fare la differenza, prova a dormire con una zanzara -- Dalai Lama

gian_d
Linux 3.x
Linux 3.x
Messaggi: 654
Iscritto il: mer 16 lug 2014, 17:35
Nome Cognome: Giancarlo Dessì
Slackware: 64 current
Kernel: 6.6.xx
Desktop: KDE 5.27
Località: Sardinia
Contatta:

Re: Creare ex novo un file di testo di n righe in uno script

Messaggio da gian_d »

Grazie mille, proprio quello che mi serviva.

cat è sicuramente migliore perché il codice è più leggibile (devo creare una desktop entry).
Per la precisione funziona cat <<EOF senza lo spazio. cat << EOF prosegue invece fino alla fine dello script restituendo un errore.

Avatar utente
joe
Iper Master
Iper Master
Messaggi: 3789
Iscritto il: ven 27 apr 2007, 11:21
Slackware: 15.0
Kernel: 5.15.38
Desktop: dwm

Re: [RISOLTO] Creare ex novo un file di testo di n righe in uno script

Messaggio da joe »

Sì la soluzione giusta è l'here document anche secondo me.
Riguardo lo spazio a me il seguente script funziona anche con enne spazi.

Codice: Seleziona tutto

$ cat hd.sh
#!/bin/bash
cat <<    eof
Ecco unhere document
here is an here document
eof
Il problema se ben ricordo era l'indentazione...
Tipo una cosa così dovrebbe dare errore:

Codice: Seleziona tutto

$ cat hd.sh
#!/bin/bash

  cat <<eof
  Ecco un here document che non funziona
  here is an here document
  eof
E infatti a me salta fuori:

Codice: Seleziona tutto

$ ./hd.sh
./hd.sh: riga 6: attenzione: here-document alla riga 3 è delimitato da un EOF (era richiesto "eof")
  Ecco un here document che non funziona
  here is an here document
  eof
C'è il modo per farlo funzionare anche con l'indentazione se serve ma va be' non mi dilungo anche perché a memoria non ricordo come si faceva, c'è da cercare un secondo sui soliti stackexchange e compagnia, o magari anche qui sul forum tra i vecchi messaggi...

gian_d
Linux 3.x
Linux 3.x
Messaggi: 654
Iscritto il: mer 16 lug 2014, 17:35
Nome Cognome: Giancarlo Dessì
Slackware: 64 current
Kernel: 6.6.xx
Desktop: KDE 5.27
Località: Sardinia
Contatta:

Re: [RISOLTO] Creare ex novo un file di testo di n righe in uno script

Messaggio da gian_d »

Ciò che mi mette in crisi è l'impostazione di alcuni parametri, non sempre la guida in linea (comando -h) o man sono esaustivi e chiari

Avatar utente
joe
Iper Master
Iper Master
Messaggi: 3789
Iscritto il: ven 27 apr 2007, 11:21
Slackware: 15.0
Kernel: 5.15.38
Desktop: dwm

Re: [RISOLTO] Creare ex novo un file di testo di n righe in uno script

Messaggio da joe »

Sugli "here document" devi cercare in rete degli esempi... è la via più spedita.
Altrimenti come ti hanno già suggerito man bash già dice qualcosa:
Here Documents
This type of redirection instructs the shell to read input from the current source until a line containing only delimiter (with no trailing blanks) is seen. All of the lines read up to that point are then used as the standard input for a command.

The format of here-documents is:

Codice: Seleziona tutto

             <<[-]word
                      here-document
              delimiter
No parameter and variable expansion, command substitution, arithmetic expansion, or pathname expansion is performed on word. If any characters in word are quoted, the delimiter is the result of quote removal on word, and the lines in the here-document are not expanded. If word is unquoted, all lines of the here-document are subjected to parameter expansion, command substitution, and arithmetic expansion, the character sequence \<newline> is ignored, and \ must be used to quote the characters \, $, and `.

If the redirection operator is <<-, then all leading tab characters are stripped from input lines and the line containing delimiter.
This allows here-documents within shell scripts to be indented in a natural fashion.

Here Strings
A variant of here documents, the format is:

Codice: Seleziona tutto

            <<<word
The word undergoes brace expansion, tilde expansion, parameter and variable expansion, command substitution, arithmetic expansion, and quote removal. Pathname expansion and word splitting are not performed. The result is supplied as a single string to the command on its standard input.

gian_d
Linux 3.x
Linux 3.x
Messaggi: 654
Iscritto il: mer 16 lug 2014, 17:35
Nome Cognome: Giancarlo Dessì
Slackware: 64 current
Kernel: 6.6.xx
Desktop: KDE 5.27
Località: Sardinia
Contatta:

Re: [RISOLTO] Creare ex novo un file di testo di n righe in uno script

Messaggio da gian_d »

Diamine, non sapevo dell'esistenza di una entry man bash, ho sempre creduto che man avesse solo lemmi che fanno riferimento specifico ai comandi, oltre a file di configurazione. Non si finisce mai di imparare.

Comunque di solito per questioni semplici ricorro all'help o a man, anche se non sempre è tutto chiaro. Se non riesco a trovare una risposta allora provo a cercare degli esempi in rete. Questa volta non ci sono riuscito.

Visto che ci sono ne approfitto per porre un altro quesito. Dove posso trovare una guida ben fatta sull'uso di sed? Mi sembra si tratti un comando alquanto potente, però non riesco a capirne due aspetti essenziali: i contesti in cui usarlo e la sintassi. Ci ho sbattuto la testa alcune volte ma non sono riuscito a cavarne piede al di là della scopiazzatura riadattata di qualche esempio.

Avatar utente
joe
Iper Master
Iper Master
Messaggi: 3789
Iscritto il: ven 27 apr 2007, 11:21
Slackware: 15.0
Kernel: 5.15.38
Desktop: dwm

Re: [RISOLTO] Creare ex novo un file di testo di n righe in uno script

Messaggio da joe »

Te lo aveva scritto sopra "targz". "man" sta per manuale eh ;)
Comunque il man bash non è proprio banale da consultare se non sai cosa cercare. In questo caso dai "man bash /here\ document" e trovi... altre volte no è così semplice. Per quello dicevo, fai prima con una ricerca in rete magari in inglese che trovi più roba...

Guide su sed ne trovi finche vuoi, anche lì c'è il man sed. Ma le manpages per conto mio in generale hanno la lacuna idi non avere esempi, e l'esempio è un buon 80% per capire le cose specie se si è a zero su un argomento.
Per il contesto, sed lavora su file di testo, quindi anche su stringhe, quindi anche su l'output che un certo comando ti restituisce sulla shell, grazie alla pipe...
Esempio sciocco:

Codice: Seleziona tutto

echo rane | sed 's/ane/ime/'
Può servire per filtrare e rielaborare certe righe di un file di testo, ecc ecc... il contesto è quello di solito, alternative sono awk specie su files con elementi incolonnati, e s no perl.

La sintassi di sed è:

Codice: Seleziona tutto

sed -opzioni indirizzo/comando inputfile
esempio:

Codice: Seleziona tutto

sed 1d file
rimuove la prima riga del file, l'indirizzo è 1, il comando è d.
poi ve ne sono altri, tipo p per print e altri ancora... insomma "man sed" in questo caso è semplice.
Uno molto usato è "s", vedi l'esempio di prima, che sta per substitute e sostituisce un certo "pattern" con qualcos'altro che gli indichi, la sintassi la vedi anche nell'esempio, comunque:

Codice: Seleziona tutto

sed 's/pattern/qualcosaltro/' inputfile
l'indirizzo può essere definito dal numero di riga come nell'esempio di rimozione sopra, ma anche come più righe, o ancora intervallo di righe, e infine anche un pattern può costituire un particolare indirizzo a cui applicare il comando.
Comunque di guide a sed ne trovi senza problemi anche per principianti in modo che sia spiegato per bene. Basta che cerchi in rete, ora al volo non te ne saprei consigliare una in particolare... Anzi, prova un po' questa roba:

https://www.grymoire.com/Unix/Sed.html

E di questo ho dato un'occhiata solo alla prima, se la prende con molta calma ma vedi tu come regolarti con la riproduzione video:

https://www.youtube.com/c/morrolinux/search?query=sed

gian_d
Linux 3.x
Linux 3.x
Messaggi: 654
Iscritto il: mer 16 lug 2014, 17:35
Nome Cognome: Giancarlo Dessì
Slackware: 64 current
Kernel: 6.6.xx
Desktop: KDE 5.27
Località: Sardinia
Contatta:

Re: [RISOLTO] Creare ex novo un file di testo di n righe in uno script

Messaggio da gian_d »

OK, mi hai dato un po' di spunti per lavorarci su. Vorrei imparare ad usarlo perché penso che sia utile quando si sta provando a compilare dei sorgenti via slackbuild per intercettare eventuali errori di compilazione o di controllo da parte di cmake. Di solito, quando capita, faccio dei tentativi con delle patch, ma quando lavori su approssimazioni successive le patch sono macchinose, mentre forse con sed si procede più speditamente.

PS: per man c'è stato un equivoco. Ho detto che non conoscevo "man bash" perché non sapevo che c'era un lemma "bash" nelle pagine di manuale.

Rispondi