Видаліть лише коси, наявні в подвійних лапках


10

У текстовому файлі я хочу видалити ,(коми), а також "(лапки) (лише якщо подвійні лапки містять числа, розділені комами).

56,72,"12,34,54",x,y,"foo,a,b,bar"

Очікуваний вихід

56,72,123454,x,y,"foo,a,b,bar"

Примітка. Наведений вище рядок я показую лише як приклад. Мій текстовий файл містить безліч рядків, як вище, і числа, розділені комами, наявними в подвійних лапках, повинні відрізнятися. Це є,

56,72,"12,34,54",x,y,"foo,a,b,bar"
56,92,"12,34",x,y,"foo,a,b,bar"
56,72,"12,34,54,78,76,54,67",x,y,"foo,a,b,bar"
56,72,x,y,"foo,a,b,bar","12,34,54"
56,72,x,y,"foo,a,b,bar","12,34,54","45,57,84,92","bar,foo"

Очікуваний вихід:

56,72,123454,x,y,"foo,a,b,bar"
56,92,1234,x,y,"foo,a,b,bar"
56,72,12345478765467,x,y,"foo,a,b,bar"
56,72,x,y,"foo,a,b,bar",123454
56,72,x,y,"foo,a,b,bar",123454,45578492,"bar,foo"

У nподвійних лапках, розділених комами, існує ряд чисел. А також залиште подвійні лапки, які містять символи як є.

Я люблю sedінструмент для обробки тексту. Я радий, якщо ви опублікуєте sedдля цього якесь рішення.


Від 56,72,"12,34,54",x,y,"foo,a,b,bar"до 56,72,123454,x,y,"a,b", fooі barзникає. Це ваш бажаний вихід?
cuonglm

Приклад, який ви використовуєте, трохи заплутаний, оскільки деякі елементи (як-от fooі bar) видаляються разом із комами. Крім того, деякі цитати зникають там, де інші залишаються. Не кажучи вже про те, що коми aі bзалишаються такими ж. Чи є до них якась закономірність?
HalosGhost

редагували шкода друзів.
Авінаш Радж

Ваші зміни не пояснили справді ваш приклад. Будь ласка, дивіться мій останній коментар .
HalosGhost

видаліть усі коми з подвійних лапок, а також лапки, лише якщо цитати містять числа.
Авінаш Радж

Відповіді:


7

Це (адаптовано звідси ) повинно робити все, що вам потрібно, хоча Perl один @ rici набагато простіше:

$ sed -r ':a;s/(("[0-9,]*",?)*"[0-9,]*),/\1/;ta; s/""/","/g; 
          s/"([0-9]*)",?/\1,/g ' file
56,72,123454,x,y,"foo,a,b,bar"
56,92,1234,x,y,"foo,a,b,bar"
56,72,12345478765467,x,y,"foo,a,b,bar"
56,72,x,y,"foo,a,b,bar",123454,
56,72,x,y,"foo,a,b,bar",123454,45578492,"bar,foo"

Пояснення

  • :a: визначте мітку під назвою a.
  • s/(("[0-9,]*",?)*"[0-9,]*),/\1/ : Це потрібно розбити
    • Перш за все, з допомогою цієї конструкції: (foo(bar)), \1буде foobarі \2буде bar.
    • "[0-9,]*",?: збігається з 0 або більше з 0-9або з ,наступним 0 або 1 ,.
    • ("[0-9,]*",?)* : збігаються з 0 або більше із зазначеного вище.
    • "[0-9,]*: Відповідає 0 або більше 0-9або ,які приходять відразу після"
  • ta;: поверніться до мітки aта запустіть знову, якщо заміна була успішною.
  • s/""/","/g;: подальша обробка. Замініть ""на ",".
  • s/"([0-9]*)",?/\1,/g : видаліть усі лапки навколо цифр.

Це може бути простіше зрозуміти з іншого прикладу:

$ echo '"1,2,3,4"' | sed -nr ':a;s/(("[0-9,]*",?)*"[0-9,]*),/\1/;p;ta;'
"1,2,34"
"1,234"
"1234"
"1234"

Отже, хоча ви можете знайти число, яке знаходиться відразу після цитати, а за ним - кома та інше число, з'єднайте два числа разом і повторіть процес, поки це вже не стане можливим.

На цей момент я вважаю, що корисно згадати цитату, info sedяка з’являється у розділі, що описує розширені функції, такі як мітка, що використовується вище (дякую, що знайшли, якщо @Braiam):

У більшості випадків використання цих команд вказує на те, що вам, мабуть, краще програмувати щось на зразок `awk 'або Perl.


10

Якщо з Perl все в порядку, ось короткий (і, мабуть, швидкий, якщо не обов'язково простий :)) спосіб зробити це:

perl -pe 's:"(\d[\d,]+)":$1=~y/,//dr:eg' file

eПрапор до s:::оператору (це просто ще один спосіб написання s///) викликає заміну слід розглядати як вираз , що обчислюється кожен раз. Цей вираз приймає $1захоплення з регулярного вираження (у якому вже відсутні лапки) і переводить ( y///що також можна записати як tr///) його, видаливши ( /d) всі коми. rПрапор yнеобхідний для того , щоб отримати значення , яке має бути перекладена рядок, замість підрахунку перекладів.

Для тих, хто якось відчуває занурення perl, ось еквівалент пітона. Python насправді не є одноланцевим інструментом оболонки, але іноді його можна використовувати за допомогою спільної роботи. Наступне можна записати як один рядок (на відміну від forциклів, якого не може бути), але горизонтальна прокрутка робить його (ще більше) нечитабельним:

python -c '
import re;
import sys;
r=re.compile("\"(\d+(,\d+)*)\"");
all(not sys.stdout.write(r.sub(lambda m:m.group(1).replace(",",""),l))
    for l in sys.stdin)
' < file

@rici: Хороший! І використовуйте y///замість того, щоб tr///врятувати нас ще один символ.
cuonglm

6

Для даних CSV я б використовував мову з реальним аналізатором CSV. Наприклад, з Ruby:

ruby -rcsv -pe '
  row = CSV::parse_line($_).map {|e| e.delete!(",") if e =~ /^[\d,]+$/; e} 
  $_  = CSV::generate_line(row)
' <<END
56,72,"12,34,54",x,y,"foo,a,b,bar"
56,92,"12,34",x,y,"foo,a,b,bar"
56,72,"12,34,54,78,76,54,67",x,y,"foo,a,b,bar"
56,72,x,y,"foo,a,b,bar","12,34,54"
56,72,x,y,"foo,a,b,bar","12,34,54","45,57,84,92","bar,foo"
END
56,72,123454,x,y,"foo,a,b,bar"
56,92,1234,x,y,"foo,a,b,bar"
56,72,12345478765467,x,y,"foo,a,b,bar"
56,72,x,y,"foo,a,b,bar",123454
56,72,x,y,"foo,a,b,bar",123454,45578492,"bar,foo"

0

Блок-котирування

Привіт Ось код Python для заміни коми на подвійні лапки, коми замінюються символом pipe (|)

Цей код Python повинен замінити коми, укладені в подвійні лапки

наприклад: x, y, z, 1,2, "r, e, t, y", h, 8,5,6

якщо замінити на Pipe x, y, z, 1,2, "r | e | t | y", h, 8,5,6

якщо замінити на null x, y, z, 1,2, "rety", h, 8,5,6

writingFile = open('FileToWrite', 'w')
with open('FileToRead') as f:

    while True:

        c = f.read(1)
        if not c:
            print ("End of file")
            break
        print ("Read a character:", c)


        if c=='"':
            writingFile.write(c) 
            c = f.read(1)
            while c != '"':
                if c== ',':
                    c= '|'
                writingFile.write(c)
                c = f.read(1)


        writingFile.write(c)


writingFile.close()

потрібно мало пояснень.
Монгрель

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