Perché il piping su "tail" modifica il contenuto di una linea?


14

Quando visualizzo il risultato di a SELECTcon MySQL Workbench, è corretto con un singolo \

max@host 10:13:58: ~$ mysql -h db-master.domain.local -uuser -ppw db -e '
>                 SELECT
>                 DISTINCT i.filesourceregexp
>                 FROM db.ImportLogFiles i'

+------------------------------------------------+
| filesourceregexp                               |
+------------------------------------------------+
| ^[0-9]{8}_1062355673_merge_google_pbn\.csv$    |
| ^[0-9]{8}_8026062435_merge_google_pbn\.csv$    |
| ^[0-9]{8}_1062355673_store_visits_report\.csv$ |
+------------------------------------------------+

max@host 10:14:10: ~$ mysql -h db-master.domain.local -uuser -ppw db -e '
                SELECT
                DISTINCT i.filesourceregexp
                FROM db.ImportLogFiles i' | tail -n +2
^[0-9]{8}_1062355673_merge_google_pbn\\.csv$
^[0-9]{8}_8026062435_merge_google_pbn\\.csv$
^[0-9]{8}_1062355673_store_visits_report\\.csv$
max@host 10:14:19: ~$ 

Ho queste opzioni in my.cnf:

[client] 
host = db-master 
user = user 
password = pass 
default-character-set=utf8

Perché il piping del risultato attraverso tailcambia l'output / la stringa? (nota il doppio \).


Ottieni lo stesso output se installi un altro comando, giusto? Per esempio mysql ... | heado mysql ... | grep 8?
terdon

Grazie per aver migliorato il mio inglese. heade grep 802raddoppia anche il * \ * max@host 10:50:48: ~$ mysql -V mysql Ver 14.14 Distrib 5.5.55, for debian-linux-gnu (x86_64) using readline 6.3
FaxMax il

quale coda stai usando? puoi condividere l'output ditail --version
amisax il

@amisax è la mia coda tail (GNU coreutils) 8.23ma ho lo stesso problema con grep o head
FaxMax

la mia bash è GNU bash, version 4.3.30(1)-release (x86_64-pc-linux-gnu)e uname -arisultati:Linux host 3.16.0-4-amd64 #1 SMP Debian 3.16.43-2+deb8u2 (2017-06-26) x86_64 GNU/Linux
FaxMax

Risposte:


32

Non è tail, è la tubazione.

mysqlusa un tabulare con formato di output di inscatolamento ASCII quando il suo stdout è un dispositivo terminale, quando è destinato a un utente, e ritorna a un formato di scripting quando non lo è, come quando è una pipe o un file normale.

Vedresti lo stesso formato diverso con

mysql... | cat

o

mysql > file; cat file

Vedi anche -r/ --raw, -s/ --silent, -B/ --batch, -N/ --skip-column-names/ --column-names=0, -H/ --html, -t/ --table... che influenzano il formato di output.

Se si desidera l'output tabulare anche quando l'output non va su un dispositivo terminale, aggiungere l' -topzione:

mysql -t ... | tail -n +2

Ma se il punto è rimuovere la riga di intestazione, basta usare -N, con o senza -t.

Qui per ottenere i valori dal database il più crudo possibile e senza intestazione, userei:

mysql --defaults-extra-file=/some/protected/file/with/credentials \
      --batch --raw --skip-column-names -e 'select...' database

Questo è:

  • non esporre la password nell'output di pspassando invece le credenziali in un file (come te my.cnf) con --defaults-extra-file.
  • utilizzare la modalità batch per evitare l'output tabulare (e riconoscere il fatto che lo stiamo effettivamente raggruppando che potrebbe avere altre implicazioni).
  • --rawper evitare la fuga . Supponendo che i valori non contengano newline poiché altrimenti l'output non potrebbe essere postelaborato in modo affidabile.
  • --skip-column-names per rimuovere la riga di intestazione.

1
le opzioni hanno -r --column-names=0risolto il mio problema, i carri armati
FaxMax il

3
Questo è lo stesso motivo per cui l' lsoutput viene inserito in colonne quando l'output viene indirizzato a un terminale, ma è una singola colonna quando si scrive in una pipe o in un file.
Barmar,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.