Как я могу получить подстроку в SQLite? - PullRequest
1 голос
/ 19 марта 2020

Есть столбец. И он имеет такие значения, как

'/ abc / def / ghi / w1.xyz'

'/ jkl / mno / r.stuv'

(это данные пути и количество символов '/' в каждом значении не является фиксированным.)


как получить столбец подстроки, который имеет значения, такие как

'/ abc / def / ghi /'

'/ jkl / mno /'

(извлечение только части каталога. Удаление части файла.)


я читал о substr (X, Y), substr (X, Y, Z), instr (X, Y).

, но их нелегко применить, потому что число '/' в каждом значении не фиксировано, а instr (X, Y) Похоже, найти первое вхождение слева.

Ответы [ 2 ]

3 голосов
/ 19 марта 2020

С рекурсивным CTE :

create table tablename(col text);
insert into tablename(col) values
('/abc/def/ghi/w1.xyz'),
('/jkl/mno/r.stuv');

with recursive cte(col, pos, rest) as (
  select col, instr(col, '/') pos, substr(col, instr(col, '/') + 1) rest
  from tablename
  union all
  select col, instr(rest, '/'), substr(rest, instr(rest, '/') + 1) 
  from cte 
  where instr(rest, '/') > 0                                        
)  
select col, substr(col, 1, sum(pos)) path
from cte                               
group by col

См. Демоверсию . Результаты:

| col                 | path          |
| ------------------- | ------------- |
| /abc/def/ghi/w1.xyz | /abc/def/ghi/ |
| /jkl/mno/r.stuv     | /jkl/mno/     |
0 голосов
/ 19 марта 2020

Если вы работаете в среде Unix / Linux, вы можете сделать что-то вроде этого (давайте рассмотрим пример).

Допустим, test.db была вашей базой данных SQLite3 с таблицей, например:

create table test (dataset text);
insert into test (dataset) values ('/abc/def/ghi/w1.xyz');
insert into test (dataset) values ('/jkl/mno/r.stuv');

Из командной строки вы можете запустить:

sqlite3 test.db -batch -noheader "select dataset from test"

Это даст вам это в качестве вывода (я знаю, что это не тот вывод, который вы хотите, а просто чтение):

/abc/def/ghi/w1.xyz
/jkl/mno/r.stuv 

Пояснение

  • переключатели -batch и -noheader подавляют все выходные данные, кроме данных, следующих из оператора SQL
  • sqlite3 test.db -batch -noheader "sql statement" запускает SQL оператор, который вы предоставили, и вывод выводится на экран (стандартный вывод)

Решение

Теперь мы будем использовать awk с ним, чтобы получить то, что вы хочу вот так:

sqlite3 test.db -batch -noheader "select dataset from test" | awk -F'/' 'BEGIN{OFS="/"} {$NF = ""; print $0}'

Результат будет:

/abc/def/ghi/
/jkl/mno/

Грубое объяснение

  • awk работает на каждой строке, выводимой вашей командой sqlite3
  • строка разделяется на / символ с -F'/' switch
  • , так как мы хотим, чтобы вывод содержал разделители как есть, мы и разделитель выходных полей также должен быть '/', используя OFS='/'
  • , мы устанавливаем количество полей (NF) таким образом, что последний элемент игнорируется, а затем печатаем оставшиеся данные
  • при печати других разделенных полей OFS вставляет / между этими полями
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...