Se vuoi farlo e rimuovi gli spazi che ti servono:
echo -n "Hello" | od -A n -t x1 | sed 's/ *//g'
I primi due comandi in cantiere sono ben spiegati da @TMS nella sua risposta, come modificato da @James. L'ultimo comando differisce dal commento @TMS in quanto è corretto ed è stato testato. La spiegazione è:
sed
è una s tream ed itatore.s
è la s comando sostituisci./
apre un'espressione regolare:è possibile utilizzare qualsiasi carattere./
è convenzionale, ma scomodo per elaborare, ad esempio, XML o nomi di percorso./
o il carattere alternativo scelto, chiude l'espressione regolare e apre la stringa di sostituzione.- In
/ */
il*
corrisponde a qualsiasi sequenza del carattere precedente (in questo caso, uno spazio). /
o il carattere alternativo che hai scelto, chiude la stringa di sostituzione. In questo caso, la stringa di sostituzione//
è vuoto, ovvero la corrispondenza è stata eliminata.g
è l'opzione per eseguire questa sostituzione g lobalmente su ogni riga anziché solo una volta per riga.- Le virgolette evitano che il parser dei comandi venga confuso:l'intera sequenza viene passata a
sed
come prima opzione, ovvero unsed
copione.
@TMS brain child (sed 's/^ *//'
) rimuove solo gli spazi dall'inizio di ogni riga (^
corrisponde all'inizio della riga - 'pattern space' in sed
-parlare).
Se vuoi anche rimuovere le nuove righe, il modo più semplice è aggiungere
| tr -d '\n'
ai tubi di comando. Funziona come segue:
|
invia il flusso elaborato in precedenza all'input standard di questo comando.tr
è il tr comando anslate.-d
specifica l'eliminazione dei caratteri di corrispondenza.- Le virgolette elencano i caratteri di corrispondenza - in questo caso solo newline (
\n
).Translate corrisponde solo a singoli caratteri, non a sequenze.
sed
è ritardato in modo univoco quando si tratta di newline. Questo perché sed
è uno dei unix
più vecchi comandi:è stato creato prima che le persone sapessero davvero cosa stavano facendo. Il software legacy pervasivo ne impedisce la correzione. Lo so perché sono nato prima del unix
è nato.
L'origine storica del problema era l'idea che una nuova riga fosse un separatore di riga, non parte della riga. È stato quindi rimosso dalle utilità di elaborazione della linea e reinserito dalle utilità di output. Il problema è che questo fa ipotesi sulla struttura dei dati dell'utente e impone restrizioni innaturali in molti contesti. sed
l'incapacità di rimuovere facilmente le nuove righe è uno degli esempi più comuni di quell'ideologia malformata che causa dolore.
È possibile rimuovere le nuove righe con sed
- è solo che tutte le soluzioni che conosco fanno sed
elaborare l'intero file in una volta, che soffoca per file molto grandi, vanificando lo scopo di un editor di flusso. Qualsiasi soluzione che mantenga l'elaborazione della linea, se possibile, sarebbe un nido di topi illeggibile di più tubi.
Se insisti nell'usare sed
prova:
sed -z 's/\n//g'
-z
dice a sed
utilizzare valori null come separatori di riga.
Internamente, una stringa in C
termina con un null. Il -z
anche l'opzione è un risultato di legacy, fornito per comodità per C
programmatori che potrebbero voler usare un file temporaneo riempito con C
-stringhe e sgombra da nuove righe. Possono quindi leggere ed elaborare facilmente una stringa alla volta. Ancora una volta, le prime ipotesi sui casi d'uso impongono restrizioni artificiali sui dati degli utenti.
Se ometti g
opzione, questo comando rimuove solo la prima nuova riga. Con il -z
opzione sed
interpreta l'intero file come una riga (a meno che non ci siano null vaganti incorporati nel file), terminata da un null e quindi questo si blocca anche su file di grandi dimensioni.
Potresti pensare
sed 's/^/\x00/' | sed -z 's/\n//' | sed 's/\x00//'
potrebbe funzionare. Il primo comando inserisce un valore null all'inizio di ogni riga riga per riga, risultando in \n\x00
terminare ogni riga. Il secondo comando rimuove una nuova riga da ogni riga, ora delimitata da null - ci sarà solo una nuova riga in virtù del primo comando. Tutto ciò che resta sono i null spuri. Fin qui tutto bene. L'idea sbagliata qui è che la pipe alimenterà l'ultimo comando riga per riga, poiché è così che è stato costruito lo stream. In realtà, l'ultimo comando, come scritto, rimuoverà solo un null poiché ora l'intero file non ha newline ed è quindi una riga.
L'implementazione di pipe semplici utilizza un file temporaneo intermedio e tutto l'input viene elaborato e inserito nel file. Il comando successivo potrebbe essere in esecuzione in un altro thread, leggendo contemporaneamente quel file, ma vede solo il flusso nel suo insieme (sebbene incompleto) e non è a conoscenza dei limiti del blocco che alimentano il file. Anche se la pipe è un buffer di memoria, il comando successivo vede il flusso nel suo insieme. Il difetto è inestricabilmente integrato in sed
.
Per far funzionare questo approccio, hai bisogno di un g
opzione sull'ultimo comando, quindi, ancora una volta, si blocca su file di grandi dimensioni.
La linea di fondo è questa:non usare sed
per elaborare le nuove righe.
echo hello | hexdump -v -e '/1 "%02X "'
echo -n "Hello" | od -A n -t x1
Spiegazione:
- Il
echo
il programma fornirà la stringa al comando successivo. - Il
-n
flag dice a echo di non generare una nuova riga alla fine del "Ciao". - Il
od
programma è il programma "dump ottale". (Forniremo un flag per dirgli di scaricarlo in esadecimale anziché in ottale.) - Il
-A n
flag è l'abbreviazione di--address-radix=n
, dove n è l'abbreviazione di "nessuno". Senza questa parte, il comando produrrebbe un brutto prefisso numerico dell'indirizzo sul lato sinistro. Questo è utile per dump di grandi dimensioni, ma per una stringa breve non è necessario. - Il
-t x1
flag è l'abbreviazione di--format=x1
, dove x è l'abbreviazione di "esadecimale" e 1 significa 1 byte.