Yalnızca çift tırnak içindeki virgülleri kaldırın


10

Bir metin dosyasında ,(virgül) ve ayrıca "(tırnak işaretleri) kaldırmak istiyorum (yalnızca çift tırnak işaretleri virgülle ayrılmış sayılar içeriyorsa).

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

Beklenen çıkış

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

Not: Yukarıdaki satırı örnek olarak göstereceğim. Metin dosyamda yukarıdaki gibi birçok satır var ve çift tırnak işaretleri arasında yer alan virgüllerle ayrılmış sayılar değişmelidir. Yani,

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"

Beklenen çıktı:

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Çift tırnak içinde virgülle ayrılmış birkaç sayı vardır . Ayrıca, karakterleri içeren çift tırnak işaretlerini olduğu gibi bırakın.

sedMetin işleme aracını seviyorum . Bunun için herhangi bir sedçözüm gönderirseniz mutlu olurum .


Dan 56,72,"12,34,54",x,y,"foo,a,b,bar"için 56,72,123454,x,y,"a,b", foove baris kaybolur. İstediğiniz çıktı mı?
cuonglm

Kullandığınız örnek , virgülle birlikte bazı öğeler ( foove gibi bar) kaldırıldığından biraz kafa karıştırıcıdır . Ayrıca, bazı alıntılar diğerlerinin kaldığı yerde kaybolur. Bahsetmiyorum bile virgül arasında ave arasında bkalır. Bunların herhangi bir örneği var mı?
HalosGhost

düzenledi üzgünüm arkadaşlar.
Avinash Raj

Yaptığınız düzenlemeler örneğinizi gerçekten netleştirmedi. Lütfen son yorumuma bakın .
HalosGhost

çift ​​tırnak içindeki tüm virgülleri ve tırnak işaretleri yalnızca sayı içeriyorsa kaldırın.
Avinash Raj

Yanıtlar:


7

@Rici's Perl One çok daha basit olsa da , bu ( buradan uyarlanır ) ihtiyacınız olanı yapmalıdır:

$ 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çıklama

  • :a: adlı etiketi tanımlayın a.
  • s/(("[0-9,]*",?)*"[0-9,]*),/\1/ : Bunun parçalanması gerekiyor
    • Her şeyden önce, bu yapı kullanılarak: (foo(bar)), \1olacak foobarve \2olacak bar.
    • "[0-9,]*",?: 0 veya daha fazla 0-9veya ,0 ve 1 ile eşleşir ,.
    • ("[0-9,]*",?)* : yukarıdakilerin 0 veya daha fazlasıyla eşleşir.
    • "[0-9,]*: 0 maç veya daha fazla 0-9veya ,a vuruşunun ardından geldiğini"
  • ta;: etikete geri dönün ve değişiklik başarılı olursaa tekrar çalıştırın .
  • s/""/","/g;: rötuş. Değiştir ""ile ",".
  • s/"([0-9]*)",?/\1,/g : sayılardaki tüm tırnak işaretlerini kaldırır.

Bunu başka bir örnekle anlamak daha kolay olabilir:

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

Dolayısıyla, bir teklifin hemen ardından gelen ve ardından bir virgül ve başka bir sayı bulabilmenize rağmen, iki sayıyı birleştirin ve artık mümkün olana kadar işlemi tekrarlayın.

Bu noktada, info sedyukarıda kullanılan etiket gibi gelişmiş işlevleri açıklayan bölümde yer alan bir alıntıdan bahsetmenin yararlı olduğuna inanıyorum (@Braiam ise bulduğunuz için teşekkürler):

Çoğu durumda, bu komutların kullanılması, muhtemelen awk veya Perl gibi bir programda daha iyi programlama yaptığınızı gösterir.


10

Perl TAMAM ise, işte kısa (ve muhtemelen basit değilse, hızlı :)) yolu:

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

Operatöre gelen ebayrak s:::(bu sadece başka bir yazma şeklidir s///), değiştirmenin her seferinde değerlendirilen bir ifade olarak ele alınmasına neden olur. Bu ifade, $1yakalamayı normalden (zaten tırnak işaretleri eksik) alır ve tüm virgülleri silerek ( ) çevirir (ve y///aynı zamanda yazılabilir tr///) /d. rİçin bayrak yyerine çevirilerin sayımı, değer tercüme dize olmak almak için gereklidir.

Bir şekilde perl tarafından küsülenmiş olanlar için, işte python eşdeğeri. Python gerçekten kabuklu tek astarlı bir araç değildir, ancak bazen birlikte çalışmaya da sokulabilir. Aşağıdakiler bir satır olarak yazılabilir ( forolamaz, döngülerden farklı olarak), ancak yatay kaydırma (daha da fazla) okunamaz hale getirir:

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: İyi biri! Ve bize bir karakter daha kaydetmek y///yerine kullanın tr///.
cuonglm

6

CSV verileri için gerçek bir CSV ayrıştırıcısı olan bir dil kullanırdım. Örneğin Ruby ile:

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

blockquote

Merhaba İşte virgül çift tırnak işareti ile değiştirmek için Python kodu, virgül boru (|) karakteri ile değiştirilir

Bu Python kodu çift tırnak içine alınmış virgüllerin yerini alacaktır

örneğin: x, y, z, 1,2, "r, e, t, y", h, 8,5,6

Boru x, y, z, 1,2, "r | e | t | y" ile değiştirilirse, h, 8,5,6

null x, y, z, 1,2, "rety", h, 8,5,6 ile değiştirilirse

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()

çok az açıklama gerekiyor.
Mongrel

Bu python kodu çift tırnak içinde bir şey değiştirmek için kullanılır
Vijay Kumar Akarapu
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.