Чому трубопровід до "хвоста" змінює вміст рядка?


14

Коли я переглядаю результат роботи SELECTз MySQL Workbench, це правильно з одним єдиним \

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: ~$ 

Ці параметри у мене є my.cnf:

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

Чому протокол результату відбувається через tailзміну виводу / рядка? (відзначимо подвійне \).


Ви отримаєте той самий вихід, якщо подаєте іншу команду, правда? Наприклад mysql ... | headабо mysql ... | grep 8?
тердон

Дякуємо, що вдосконалили мою англійську. headа grep 802також подвойте * \ * 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

який хвіст ви використовуєте? Ви можете поділитися результатамиtail --version
amisax

@amisax мій хвіст, tail (GNU coreutils) 8.23але у мене така ж проблема з
грепом

мій баш GNU bash, version 4.3.30(1)-release (x86_64-pc-linux-gnu)та uname -aрезультати:Linux host 3.16.0-4-amd64 #1 SMP Debian 3.16.43-2+deb8u2 (2017-06-26) x86_64 GNU/Linux
FaxMax

Відповіді:


32

Це не так tail, це трубопроводи.

mysqlвикористовує таблицю з вихідним форматом боксу ASCII, коли її stdout є термінальним пристроєм, коли він призначений для користувача, і повертається до формату сценаріїв , коли його немає, як, наприклад, це труба або звичайний файл.

Ви б побачили той самий різний формат із

mysql... | cat

або

mysql > file; cat file

Дивіться також -r/ --raw, -s/ --silent, -B/ --batch, -N/ --skip-column-names/ --column-names=0, -H/ --html, -t/ --table..., які впливають на вихідний формат.

Якщо ви хочете табличний вихід навіть тоді, коли вихід не переходить до термінального пристрою, додайте -tпараметр:

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

Але якщо справа в тому, щоб видалити рядок заголовка, просто використовуйте -N, з або без -t.

Тут, щоб отримати значення з бази даних як можна сиріші та без заголовка, я б використав:

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

Тобто:

  • не виставляйте пароль на виході ps, передаючи облікові дані замість файлу (як ви my.cnf) --defaults-extra-file.
  • використовуйте пакетний режим, щоб уникнути табличного виводу (і визнати той факт, що ми насправді його створюємо, що може мати інші наслідки).
  • --rawщоб уникнути втечі . Припустимо, що значення не містять нових рядків, інакше вихід не може бути надійно оброблений.
  • --skip-column-names щоб видалити рядок заголовка.

1
варіанти -r --column-names=0вирішили мою проблему, танки
FaxMax

3
Це та сама причина, що lsвихід виводиться на стовпці, коли вихід надходить до терміналу, але є одним стовпцем під час запису в трубу чи файл.
Бармар
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.