it-swarm-id.com

Bagaimana saya bisa membuat iconv mengganti file input dengan output yang dikonversi?

Saya memiliki skrip bash yang menyebutkan setiap file * .php dalam direktori dan menerapkan iconv untuknya. Ini mendapatkan output dalam STDOUT.

Sejak menambahkan -o parameter (menurut pengalaman saya) sebenarnya menulis file kosong mungkin sebelum konversi terjadi, bagaimana saya bisa menyesuaikan skrip saya sehingga melakukan konversi, lalu menimpa file input?

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

Ini tidak berfungsi karena iconv pertama kali membuat file output (karena file sudah ada, itu memotongnya), kemudian mulai membaca file inputnya (yang sekarang kosong). Sebagian besar program berperilaku seperti ini.

Buat file sementara yang baru untuk output, kemudian pindahkan ke tempatnya.

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

Jika platform Anda iconv tidak memiliki -o, Anda dapat menggunakan pengalihan Shell untuk efek yang sama.

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

Utilitas sponge Colin Watson (termasuk dalam moreutils Joey Hess ) mengotomatiskan ini:

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

Jawaban ini berlaku tidak hanya untuk iconv tetapi untuk setiap program filter. Beberapa kasus khusus perlu disebutkan:

  • GNU sed dan Perl -p memiliki -i pilihan untuk mengganti file di tempat.
  • Jika file Anda sangat besar, filter Anda hanya memodifikasi atau menghapus beberapa bagian tetapi tidak pernah menambahkan sesuatu (mis. grep, tr, sed 's/long input text/shorter text/'), dan Anda suka hidup dalam bahaya, Anda mungkin ingin benar-benar memodifikasi file di tempat (solusi lain yang disebutkan di sini membuat file output baru dan pindahkan ke tempatnya pada akhir, sehingga data asli tidak berubah jika perintah terputus karena alasan apa pun).

Alternatifnya adalah recode, yang menggunakan perpustakaan libiconv untuk beberapa konversi. Perilakunya adalah mengganti file input dengan output, jadi ini akan berfungsi:

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

Karena recode menerima beberapa file input sebagai parameter, Anda dapat menyimpan loop for:

recode cp1251..utf8 *.php
61
manatwork

Untuk sekarang

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

bekerja seperti pesona

4
galeksandrp

Anda dapat menggunakan Vim dalam mode Ex:

ex -sc '%!iconv -f cp1251 -t utf8' -cx "$file"
  1. % pilih semua baris

  2. ! jalankan perintah

  3. x simpan dan tutup

1
Steven Penny

Salah satu opsi adalah menggunakan antarmuka Perl untuk iconv dan -i mode untuk mengedit di tempat:

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

Dengan GNU awk, Anda juga dapat melakukan sesuatu seperti:

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

ksh93 Shell juga memiliki >; operator untuk itu yang menyimpan output dalam file temp yang diubah namanya menjadi file yang diarahkan jika perintah berhasil:

for f in *.php; do
  iconv -f cp1252 -t utf-8 < $f >; $f
done
0

Ini adalah contoh sederhana . Seharusnya memberi Anda cukup info untuk memulai.

#!/bin/bash
#conversor.sh
#Author.....: dede.exe
#E-mail.....: [email protected]
#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
dede.exe
echo "`iconv -f cp1251 -t utf8 $file`" > "$file"

bekerja untukku

0
CoNsTaR

Anda dapat menggunakan find, setidaknya ini berfungsi untuk saya di Raspbian Stretch:

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