CSV dosyanız Excel'de neden yanlış açılıyor

Yerel ayara göre virgül, noktalı virgül ve sekme; ayrıca tırnaklama, kaçış, UTF-8 BOM ve bir dosyanın gerçekte hangi ayırıcıyı kullandığını bulmanın güvenilir bir yolu.

Excel, bir .csv dosyasının nasıl ayrıldığını anlamak için içine bakmaz. Böyle bir dosyaya çift tıkladığınızda, işletim sisteminizin bölge ayarlarındaki liste ayırıcısını kullanır ve bu ayırıcı dosyayla uyuşmuyorsa her satır tek bir sütuna düşer.

Birleşik Krallık ve ABD'de liste ayırıcısı virgüldür. Kıta Avrupası'nın çoğunda ve Latin Amerika'nın büyük bölümünde, yani ondalık ayırıcının virgülle yazıldığı yerlerde liste ayırıcısı noktalı virgüldür. Bu yüzden Londra'dan postalanan geçerli bir virgülle ayrılmış dosya, Amsterdam'da, Berlin'de ya da Madrid'de tek bir ezik sütun olarak açılır; noktalı virgüllü bir dosya da tersi yönde aynısını yapar. Hiçbir şey bozulmamıştır; dosya yanlış varsayımla okunmaktadır.

Doğru açmanın üç yolu

  1. Açmak yerine içe aktarın. Excel'de Veri, ardından Veri Al ya da Metinden/CSV'den yolunu izleyin ve ayırıcı ile kodlamayı iletişim kutusunda seçin. Size tam denetim veren tek yol budur ve başka bir ülkeye gönderilmekten sağ çıkan da tek yoldur.
  2. Dosyayı .txt olarak yeniden adlandırın. Excel bir .txt dosyası için tahmin yürütmeyi reddeder ve bunun yerine ayırıcının ne olduğunu size soran içe aktarma sihirbazını gösterir.
  3. Dosyayı, okuyucunun beklediği ayırıcıya çevirin, hem de göndermeden önce. Alıcının noktalı virgül kullanan bir yerel ayarda olduğunu biliyorsanız ona noktalı virgüllü bir dosya gönderin.

sep= satırı

Excel de LibreOffice de yerel ayarı geçersiz kılan özel bir ilk satırı anlar:

sep=;
name;email;country
Ada;ada@example.com;UK

İşe yarar ve "müşteri dışa aktardığım dosyayı açamıyor" sorununun sık kullanılan çözümüdür. Ancak bunun bir hesap tablosu geleneği olduğunu, herhangi bir CSV şartnamesinin parçası olmadığını bilin. Aynı dosyayı bir betiğe ya da bir veritabanı içe aktarımına verin, sep=; sıradan bir ilk satır olarak okunur ve genellikle uydurma bir sütun başlığına dönüşür. Bunu hesap tablosu kullanan bir insana gidecek dosyalar için kullanın, makineden makineye alışveriş için değil.

Tırnaklama ve kaçış

CSV'nin gayriresmî başvuru metni RFC 4180'dir; kuralı dayatmaktan çok yaygın uygulamayı anlatır. Kuralları kısadır:

  • Bir alan, ayırıcıyı, bir çift tırnağı ya da bir satır sonunu içeriyorsa çift tırnak içine alınmalıdır.
  • Tırnaklı bir alanın içindeki çift tırnak iki kez yazılır.
id,name,note
1,"Smith, Ada","She said ""hello"" twice"
2,"Multi
line note",fine

1 numaralı satırda dört değil üç alan vardır, çünkü virgül tırnakların içinde durur. İkiye katlanmış tırnaklar ayrıştırılırken tek tırnağa iner. 2 numaralı satır, tırnaklı bir alanın içinde gerçek bir satır sonu barındırır; bu geçerlidir ve bir CSV'yi satır sayarak güvenilir biçimde bölememenizin nedenidir.

Ters eğik çizgiyle kaçış (\, ya da \") bazı veritabanı araçlarının kullandığı farklı bir gelenektir. RFC 4180 değildir ve katı bir ayrıştırıcı bunu anlamaz, dolayısıyla dosyanız ters eğik çizgi kullanıyorsa onu okuyacak olan şeye bunu açıkça söyleyin.

Vahşi doğada en sık görülen arıza, dize birleştirmeyle yazılmış bir dosyadır; orada virgül ya da başıboş bir tırnak içeren bir değer hiç tırnaklanmamıştır. Bu, başlıktan daha çok alanı olan satırlar üretir ki bir doğrulayıcının parmak basacağı şey tam olarak budur.

BOM ve aksanlı karakterlerin neden mojibake'ye dönüştüğü

Bayt sırası işareti (BOM), bir dosyanın en başındaki, onu UTF-8 olarak imleyen üç görünmez bayttır. Windows'taki Excel geçmişte buna güvenmiştir: BOM olmadığında eski bir bölgesel kodlamaya düşebilir, dolayısıyla Müller karşınıza Müller, café ise café olarak çıkar.

Bunun bedeli, başka ayrıştırıcıların BOM'u her zaman ayıklamamasıdır. Betiğiniz ilk sütunun adını id yerine \ufeffid olarak bildiriyorsa ya da "id" üzerinden yapılan bir arama gizemli biçimde yalnızca ilk sütunda başarısız oluyorsa suçlu BOM'dur. Dosyayı utf-8-sig kodlamasıyla okuyun, sorun ortadan kalkar.

Pratik kural: Excel'de açılacak dosyalara BOM koyun, yazılımın ayrıştıracağı dosyalara koymayın.

Satır sonları

Windows araçları her satırın sonuna \r\n yazar, Unix araçları \n yazar. Çoğu ayrıştırıcı ikisiyle de baş eder, ama \n üzerinden yapılan naif bir bölme her satırın son alanına yapışık bir satır başı bırakır; UK gibi görünen bir değerin karşılaştırmalarda "UK" değerine eşit olmayı reddetmesinin nedeni budur.

Bir dosyanın gerçekte hangi ayırıcıyı kullandığı nasıl anlaşılır

Dosyayı düz bir metin düzenleyicide açın, asla bir hesap tablosunda açmayın, çünkü hesap tablosu tahminini çoktan yapmıştır. Sonra:

  1. İlk iki ya da üç satıra bakın. Açıkça alan değeri olan şeylerin arasında hangi aday karakter (virgül, noktalı virgül, sekme, dik çizgi) geçiyor?
  2. Her adayı birkaç satırda sayın. Gerçek ayırıcı her satırda aynı sayıyı verir ve bu sayı sütun sayısından bir eksiktir. Bir satırda yedi, bir sonrakinde iki kez geçen bir karakter yapı değil veridir.
  3. Bu saymayı tırnaklı bölümlerin dışında yapın. "Smith, Ada" içinde virgül içeriktir ve onu düşüncesizce saymak, gerçekten virgülle ayrılmış bir dosyada virgüllerin tutarsız görünmesine yol açar.
  4. Ondalık virgüllere dikkat edin. Bir Avrupa dosyasında çoğu zaman hem noktalı virgül ayırıcılar hem de sayıların içinde virgüller bulunur, Ada;1.234,56;UK örneğindeki gibi. Virgülleri yalnızca rakamların arasında görüyorsanız bunlar ayırıcı değil ondalık işaretidir.
  5. Herhangi bir sonuca varmadan önce ilk baytlarda sep= satırı ya da BOM var mı diye bakın.

Sekmeler ayrı bir bahsi hak eder. Sekmeyle ayrılmış bir dosya, genellikle bir hesap tablosuna verilebilecek en güvenli şeydir, çünkü sekmeler gerçek değerlerin içinde neredeyse hiç geçmez ve Excel içe aktarma yoluyla onları iyi karşılar. İşin püf noktası, sekmelerin görünmez olmasıdır: birinin sütunları boşlukla hizaladığı bir dosya birebir aynı görünür ve ayrıştırıldığında işe yarar hiçbir şey vermez.

Ayırıcıyı öğrendikten sonra dosyayı çevirmek mekanik bir iştir: doğru sınırlayıcı ve tırnaklama ile okuyun, sonra hedefinizin beklediği ayırıcıyla yazın; ya da JSON'a çevirip ayırıcı sorusunu tümüyle atlayın.