Почему трубопровод «хвост» меняет содержимое строки?

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изменение выходных данных / строк? (обратите внимание на двойной \).

FaxMax
источник
Вы получите тот же вывод, если передадите по конвейеру другую команду, верно? Например 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
удвойте
какой хвост ты используешь? tail --version
Можете
@amisax у меня хвост, tail (GNU coreutils) 8.23но у меня такая же проблема с grep или головой
FaxMax
мой bash 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, когда его стандартный вывод является оконечным устройством, когда он предназначен для пользователя, и возвращается к формату сценариев , когда это не так, например, когда это канал или обычный файл.

Вы бы увидели тот же другой формат с

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вывод помещается в столбцы, когда вывод поступает на терминал, но является одним столбцом при записи в канал или файл.
Бармар