İconv giriş dosyasını dönüştürülen çıktıyla değiştirmesini nasıl sağlayabilirim?


70

Bir dizindeki her * .php dosyasından geçen ve iconvbunun için geçerli olan bir bash betiğim var. Bu STDOUT'da çıktı alır.

-oParametre ekleme (deneyimlerime göre) aslında dönüşüm gerçekleşmeden önce muhtemelen boş bir dosya yazdığından, betiğimi nasıl dönüştürür, böylece dönüştürmeyi gerçekleştirir, ardından girdi dosyasının üzerine yazar?

for file in *.php
do
    iconv -f cp1251 -t utf8 "$file"
done

Ayrıca “>” ile ilgili Uyarı'ya bakınız .
G-Man

Yanıtlar:


76

Bu işe yaramıyor çünkü iconvilk önce çıktı dosyasını yaratıyor (dosya zaten mevcut olduğundan onu kısaltıyor), sonra giriş dosyasını okumaya başladı (şimdi boş). Çoğu program bu şekilde davranır.

Çıktı için yeni, geçici bir dosya oluşturun, sonra yerine yerleştirin.

for file in *.php
do
    iconv -f cp1251 -t utf8 -o "$file.new" "$file" &&
    mv -f "$file.new" "$file"
done

Platformunuzun iconvyoksa -o, aynı etkiye bir kabuk yeniden yönlendirme kullanabilirsiniz.

for file in *.php
do
    iconv -f cp1251 -t utf8 "$file" >"$file.new" &&
    mv -f "$file.new" "$file"
done

Colin Watson'ın spongeyardımcı programı ( Joey Hess'in daha fazla içeriğine dahil edilmiş ) bunu otomatikleştirir:

for file in *.php
do
    iconv -f cp1251 -t utf8 "$file" | sponge "$file"
done

Bu cevap sadece iconvherhangi bir filtre programına uygulanmaz. Birkaç özel durumdan bahsetmeye değer:

  • GNU sed ve Perl -p, -idosyaları yerinde değiştirme seçeneğine sahiptir.
  • Dosyanız çok büyükse, filtreniz yalnızca bazı kısımları değiştiriyor veya kaldırıyor, ancak hiçbir şey eklemiyor (örn grep. tr, sed 's/long input text/shorter text/') Ve tehlikeli bir şekilde yaşamaktan hoşlanıyorsanız , dosyayı yerinde gerçekten değiştirmek isteyebilirsiniz (burada belirtilen diğer çözümler bir yeni çıktı dosyasını alın ve sonunda yerine yerleştirin, böylece herhangi bir nedenle komut kesilirse orijinal veriler değiştirilmez).

3
Yazarlığının spongetamamen Joey Hess'e atfedilmesi gerekip gerekmediğinden emin değilim ; o paket moreutilsiçerir spongediye koruduğunu, ancak kökeni konusundaki spongeana bağlantıları izleyerek, moreutilsben başlangıçta buldum yayınlanmıştır ve dahil edilmesi için önerilen Colin Watson tarafından: "Joey yeni araçlar eksikliği hakkında yazıyor o Unix felsefesine uyuyorum. Yazdığım bu şeylerden en sevdiğim şey sponge"(Pzt, 06 Şubat 2006).
imz - Ivan Zakharyaschev

3
Mac OS kullanıyorum, iconv'da -o seçeneği yok, `iconv -f cp1251 -t utf8 -o" $ file.new "" $ file "` ıiconv -f cp1251 -t utf8 "$file" > "$file.new"
code4j 6:14

Bazı komutlar, parametre sortile ilgili oldukça zekicedir -ove çıktı dosyasının girdiyle aynı olduğunu tespit ederlerse dahili olarak bir temp dosyasını yönetirler, böylece sadece çalışırlar.
jesjimher

56

Alternatif olarak recode, bazı dönüşümler için libiconv kitaplığını kullanır. Davranışı, girdi dosyasını çıktı ile değiştirmektir, bu yüzden işe yarayacaktır:

for file in *.php
do
    recode cp1251..utf8 "$file"
done

Gibi recodeparametre olarak birden fazla giriş dosyalarını kabul, onu kurtarabilirsin fordöngü:

recode cp1251..utf8 *.php

2
Teşekkürler, bu daha fazla oy hakkı hak ediyor. Sadece kodlamaların arasındaki 2 noktayla ilgili olarak el ile nereye bakıldığını merak ediyorum ...
neurino

2
“İSTEK genellikle ÖNCE gibi görünüyor ... ÖNCE ve SONRA karakteristik karakterlerden ÖNCE.” Bu el kitabının, söz konusu iki noktayla (sözdiziminin bir parçası olan) ve üçlü noktalarla (bunun daha fazla ifade ettiği) takip etmesi gerçekten zor. Bir tavsiye: info recodeyerine deneyin . Daha ayrıntılı.
Manatwork

4

Şimdilik

find . -name '*.php' -exec iconv -f CP1251 -t UTF-8 {} -o {} \;

tıkır tıkır çalışıyor


5
İlk başta, gerçekten işe yaradığını düşündüm. Ancak, 32K'yi geçen çıktının kesildiği görülüyor ve daha da fazla girdi olduğunda çekirdek dökümlerini tetikliyor.
x-yuri

1

Vim'i Ex modunda kullanabilirsiniz:

ex -sc '%!iconv -f cp1251 -t utf8' -cx "$file"
  1. % tüm satırları seç

  2. ! run komutu

  3. x kaydet ve kapat


0

İşte basit bir örnek . Başlamak için size yeterli bilgi vermelidir.

#!/bin/bash
#conversor.sh
#Author.....: dede.exe
#E-mail.....: dede.exe@gmail.com
#Description: Convert all files to a another format
#             It's not a safe way to do it...
#             Just a desperate script to save my life...
#             Use it such a last resort...

to_format="utf8"
file_pattern="*.java"

files=`find . -name "${file_pattern}"`

echo "==================== CONVERTING ===================="

#Try convert all files in the structure
for file_name in ${files}
do
        #Get file format
        file_format=`file $file_name --mime-encoding | cut -d":" -f2 | sed -e 's/ //g'`

        if [ $file_format != $to_format ]; then

                file_tmp="${unit_file}.tmp"

                #Rename the file to a temporary file
                mv $file_name $file_tmp

                #Create a new file with a new format.
                iconv -f $file_format -t $to_format $file_tmp > $file_name

                #Remove the temporary file
                rm $file_tmp

                echo "File Name...: $file_name"
                echo "From Format.: $file_format"
                echo "To Format...: $to_format"
                echo "---------------------------------------------------"

        fi
done;

0
echo "`iconv -f cp1251 -t utf8 $file`" > "$file"

benim için çalışıyor


0

En azından Raspbian Stretch'te bu işe yaradı.

find . -type f -name '*php' -execdir iconv -f cp1251 -t UTF-8 '{}' -o '{}'.tmp \; -execdir mv '{}'.tmp '{}' \;

0

Seçeneklerden biri, perlarayüzünü iconvve -iyerinde düzenleme için modunu kullanmaktır:

perl -MText::Iconv -i -pe '
  BEGIN{$i=Text::Iconv->new(qw(cp1252 UTF-8));$i->raise_error(1)}
  $_ = $i->convert($_)' ./*.php

GNU ile awkayrıca şöyle bir şey yapabilirsiniz:

gawk -v cmd='iconv -f cp1252 -t utf-8' -i inplace '
  {print | cmd}; ENDFILE {close(cmd)}' ./*.php

ksh93Kabuk ayrıca sahiptir >;komut başarılı olup olmadığını yönlendirildi dosyaya yeniden adlandırıldı geçici dosyasındaki çıktıyı saklayan bunun için operatöre:

for f in *.php; do
  iconv -f cp1252 -t utf-8 < $f >; $f
done
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.