Batch converteren van latijns-1-bestanden naar utf-8 het gebruik van iconv

Ik heb dit een PHP project op mijn OSX, die in de latin1 -codering. Nu moet ik om bestanden te converteren naar UTF8. Ik ben niet zo een shell-coder en ik probeerde wat vond ik van internet:

mkdir new  
for a in `ls -R *`; do iconv -f iso-8859-1 -t utf-8 <"$a" >new/"$a" ; done

Maar dat is niet het maken van de directory structuur en het geeft me heck laden van de fouten bij het uitvoeren. Kan iemand komen met een nette oplossing?

  • Wat zijn de foutmeldingen?
  • Het probeert om mappen als bestanden en iconv geeft “niet zo’ bestand ‘ – fouten.
  • lees mijn antwoord over enconv in de thread stackoverflow.com/questions/9310571/…
InformationsquelleAutor Jasmo | 2010-12-28

 

11 Replies
  1. 41

    Moet je het niet gebruiken ls en een for loop is niet passend. Ook de doelmap moet worden buiten de bron directory.

    mkdir /path/to/destination
    find . -type f -exec iconv -f iso-8859-1 -t utf-8 "{}" -o /path/to/destination/"{}" \;

    Geen noodzaak voor een lus. De -type f optie bevat bestanden en mappen uitsluit.

    Edit:

    De OS X versie van iconv niet de -o optie. Probeer dit:

    find . -type f -exec bash -c 'iconv -f iso-8859-1 -t utf-8 "{}" > /path/to/destination/"{}"' \;
    • Ik gebruikt dit script met geen geluk. Voor de exacte parameters en resultaten, zie pastebin.com/U2D0PpWr . Er was veel uitvoer voor elk bestand (het gedrukte ze op het scherm) en foutberichten voor elk bestand, maar ik denk dat je het idee van die ene. Ik zou u dankbaar zijn als u zou ontwikkelen, deze een beetje verder 🙂
    • Zie mijn bewerkt antwoord.
    • Dit werkt niet als het bestand bestaat een aantal submappen naar beneden omdat de echo of -o pad zegt: “No such file or directory” omdat het niet maken van de bovenliggende mappen in de output locatie.
  2. 16

    Aantal goede antwoorden, maar ik vond deze een stuk makkelijker in mijn geval met een geneste map van honderden bestanden om te zetten:

    WAARSCHUWING: Dit zal de bestanden schrijven in de plaats, dus maak een back-up

    $ vim $(find . -type f)
    
    # in vim, go into command mode (:)
    :set nomore
    :bufdo set fileencoding=utf8 | w
    • Je hoeft niet in te voeren vim om dit te doen. Het volgende commando doet hetzelfde: vim "+set nomore" "+bufdo set fileencoding=utf8 | w" "+q" $(find . -type f)
  3. 11

    Dit converteert alle bestanden met de .php extensie – in de actuele map en zijn submappen – het behoud van de directory structuur:

        find . -name "*.php" -exec sh -c "iconv -f ISO-8859-1 -t UTF-8 {} > {}.utf8"  \; -exec mv "{}".utf8 "{}" \;

    Opmerkingen:

    Om een lijst van bestanden die zijn gericht op voorhand, gewoon de opdracht uitvoeren zonder de -exec vlaggen (zoals deze: find . -name "*.php"). Het maken van een back-up is een goed idee.

    Met sh zoals deze staat van de leidingen en het omleiden van met -exec, dat is nodig, want niet alle versies van iconv ondersteuning van de -o vlag.

    Toevoegen .utf8 aan de bestandsnaam van de output en verwijderen, het lijkt misschien vreemd, maar het is noodzakelijk. Het gebruik van dezelfde naam voor de output en de input-bestanden kan de volgende problemen veroorzaken:

    • Voor grote bestanden (rond de 30 KB in mijn ervaring) veroorzaakt core dump (of termination by signal 7)

    • Sommige versies van iconv lijken te maken van de output-bestand voordat ze lezen de input-bestand, wat betekent dat als de input en output-bestanden hebben dezelfde naam, de input bestand is overschreven met een leeg bestand voordat het wordt gelezen.

    • Dit werkt goed, bedankt! Echter, wanneer niet alle bestanden zijn in latijns-1, hoe is het mogelijk om alleen het converteren van de bestanden die nodig? IOW, het toevoegen van de controle met de file opdracht?
    • Een file is een reeks van bytes, of ze maken meer zin geïnterpreteerd als UTF-8-tekens of latijns-1 de symbolen alleen een mens kan weten. Echter, als u het uiterlijk van een bepaald symbool – voor een voorbeeld à – om te bepalen of een bestand opnieuw moet worden gecodeerd of niet via een filter kunt u de bestanden metgrep en rencode met xargs, zoals: grep --files-with-matches --recursive 'Ã' | xargs "iconv -f ISO-8859-1 -t UTF-8 {} > {}.utf8 ; -exec mv {}.utf8 {}" (opmerking: deze code is niet getest zijn, en zorg ervoor dat uw shell is het gebruik van UTF-8)
  4. 9

    Om te zetten in een volledige directory-boom recursief van iso-8859-1 en utf-8-met inbegrip van de oprichting van de mappen geen van de korte bovenstaande oplossingen werkte voor mij, omdat de directory structuur werd niet gemaakt in het doel. Gebaseerd op Dennis Williamsons antwoord ik kwam met de volgende oplossing:

    find . -type f -exec bash -c 't="/tmp/dest"; mkdir -p "$t/`dirname {}`"; iconv -f iso-8859-1 -t utf-8 "{}" > "$t/{}"' \;

    Het maken van een kloon van de huidige directory structuur in /tmp/dest (aan te passen aan uw wensen) inclusief alle submappen en met alle iso-8859-1 bestanden geconverteerd naar utf-8. Getest op macosx.

    Btw: Controleer uw bestand coderingen met:

    file -I file.php

    om de codering van informatie.

    Hoop dat dit helpt.

    • Het is eigenlijk file -i om te controleren van een bestand codering.
    • Bedankt – dat was perfect 🙂 (Debian Unix-in mijn geval)
  5. 5

    Als alle bestanden die u hebt om te zetten zijn .php kunt u het volgende, dat is recursief standaard:

    for a in $(find . -name "*.php"); do iconv -f iso-8859-1 -t utf-8 <"$a" >new/"$a" ; done

    Ik geloof dat je fouten waren het gevolg van het feit dat ls -R ook produceert een output die niet kunnen worden herkend door iconv als een geldige bestandsnaam, iets als ./my/dir/structure:

    • Of dit wat wordt gebruikgemaakt van originele bestandsnamen: $ for a in $(find . -name "*.java"); do iconv -f iso-8859-1 -t utf-8 <"$a" >"$a".utf8 ; done $ for a in $(find . -name "*.java.utf8"); do mv "$a" mapnaam “$a”/basename “$a” .utf8; done
  6. 5

    Ik maak het volgende script dat (i) back-ups van alle tex-bestanden in de directory “omgezet”, (ii) controleert de codering van elke tex-bestand, en (iii) omgezet naar UTF-8 alleen de tex-bestanden in het ISO-8859-1 codering.

    FILES=*.tex
    for f in $FILES
    do
      filename="${f%.*}"
      echo -n "$f"
    #file -I $f
      if file -I $f | grep -wq "iso-8859-1"
      then
        mkdir -p converted
        cp $f ./converted
        iconv -f ISO-8859-1 -t UTF-8 $f > "${filename}_utf8.tex"
        mv "${filename}_utf8.tex" $f
        echo ": CONVERTED TO UTF-8."
      else
        echo ": UTF-8 ALREADY."
      fi
    done
    • +!1 dat is de juiste oplossing, want ik herinner me dat ik problemen wanneer een bestand werd al utf-8, en ja, het was een “gemengde” – project met iso-8859-1 en utf8-bestanden. Dus ik kwam met een soortgelijke oplossing. Ik voegde mijn antwoord.
  7. 4

    Op unix.stackexchange.com een soortgelijke vraag werd gesteld en door de gebruiker manatwork voorgesteld recode dat doet de truc heel mooi.

    Ik gebruik het om te zetten ucs-2 om utf-8 in plaats

    recode ucs-2..utf-8 *.txt
  8. 1

    Alles is in orde met de bovenstaande antwoorden, maar als dit een “gemengde” – project, dat wil zeggen dat er al UTF8-bestanden, dan kunnen we in de problemen komen, dus hier is mijn oplossing, ik ben het controleren van bestandscodering eerste.

    #!/bin/bash
    # file name: to_utf8
    
    # current encoding:
    encoding=$(file -i "$1" | sed "s/.*charset=\(.*\)$/\1/")
    
    if [  "${encoding}" = "iso-8859-1" ] || [ "${encoding}" = "iso-8859-2" ]; 
    then
    echo "recoding from ${encoding} to UTF-8 file : $1"
    recode ISO-8859-2..UTF-8 "$1"
    fi
    
    #example:
    #find . -name "*.php" -exec to_utf8 {} \;
  9. 0

    Met behulp van de antwoorden van Dennis Williamson en Alberto Zaccagni, kwam ik met het volgende script converteert alle bestanden van de opgegeven bestandstype uit alle submappen. De uitgang wordt dan verzameld in een map die is opgegeven door /path/to/destination

    mkdir /path/to/destination
    for a in $(find . -name "*.php"); 
    do 
            filename=$(basename $a);
            echo $filename
            iconv -f iso-8859-1 -t utf-8 <"$a" >"/path/to/destination/$filename"; 
    done

    De functie basename geeft de bestandsnaam zonder pad van het bestand.

    Alternatief (gebruiker interactief):
    Nu heb ik ook gemaakt met een gebruiker interactief script dat kunt u zelf beslissen of u wilt de oude bestanden overschrijven of gewoon de naam ervan wijzigen. Extra dank gaat uit naar tbsalling

    for a in $(find . -name "*.tex");
    do
            iconv -f iso-8859-1 -t utf-8 <"$a" >"$a".utf8 ;
    done
    echo "Should the original files be replaced (Y/N)?"
    read replace
    if [ "$replace" == "Y" ]; then
        echo "Original files have been replaced."
        for a in $(find . -name "*.tex.utf8");
            do
                file_no_suffix=$(basename -s .tex.utf8 "$a");
                directory=$(dirname "$a");
                mv "$a" "$directory"/"$file_no_suffix".tex;
            done
    else
            echo "Original files have been converted and converted files were saved with suffix '.utf8'"
    fi

    Veel plezier met dit en ik zou dankbaar zijn voor alle reacties te verbeteren, bedankt!

  10. 0
    find . -iname "*.php" | xargs -I {} echo "iconv -f ISO-8859-1 -t UTF-8 \"{}\" > \"{}-utf8.php\""
    • stappen van het bestand…ex: \”{}-utf8.php\”

Geef een reactie

Het e-mailadres wordt niet gepubliceerd. Vereiste velden zijn gemarkeerd met *