iconv가 입력 파일을 변환된 출력으로 바꾸도록 하려면 어떻게 해야 합니까?

iconv가 입력 파일을 변환된 출력으로 바꾸도록 하려면 어떻게 해야 합니까?

디렉토리의 모든 *.php 파일을 열거하고 적용하는 bash 스크립트가 있습니다 iconv. 그러면 STDOUT으로 출력이 표시됩니다.

내 경험에 따르면 매개변수를 추가하면 -o변환이 발생하기 전에 실제로 빈 파일이 작성될 수 있으므로 변환을 수행한 다음 입력 파일을 덮어쓰도록 스크립트를 어떻게 조정해야 합니까?

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

답변1

iconv출력 파일이 먼저 생성된 다음(파일이 이미 존재하므로 잘림) 입력 파일(현재는 비어 있음)을 읽기 시작하기 때문에 이 방법은 작동하지 않습니다 . 이것이 대부분의 프로그램이 작동하는 방식입니다.

출력을 위한 새 임시 파일을 생성하고 해당 위치로 이동합니다.

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

플랫폼 iconv에 없는 경우 -o쉘 리디렉션을 사용하여 동일한 효과를 얻을 수 있습니다.

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

콜린 왓슨의 sponge유틸리티(포함 된Joey Hess의 moreutils) 이 작업을 자동으로 수행합니다.

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

iconv이 답변은 필터링 프로그램 에만 적용되는 것이 아닙니다 . 몇 가지 특별한 경우는 언급할 가치가 있습니다:

  • GNU sed와 Perl에는 파일을 대체하는 옵션이 -p있습니다 .-i
  • 파일이 매우 큰 경우 필터는 일부 부분만 수정하거나 제거하고 항목(예:,,, grep)을 추가하지 않으며 위험하게 살고 싶어할 수 있습니다.trsed 's/long input text/shorter text/'그 자리에서 파일 수정(여기에 언급된 다른 솔루션은 새 출력 파일을 생성하여 마지막 위치로 이동하므로 어떤 이유로든 명령이 중단되더라도 원본 데이터는 변경되지 않습니다.)

답변2

또는 recodelibiconv 라이브러리를 사용하여 일부 변환을 수행합니다. 그 동작은 입력 파일을 출력으로 바꾸는 것이므로 다음과 같이 작동합니다.

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

여러 입력 파일이 인수로 허용 되므로 루프를 recode저장할 수 있습니다 for.

recode cp1251..utf8 *.php

답변3

현재

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

기적적으로 효과적

답변4

여기 하나 있어요간단한 예. 시작하기에 충분한 정보를 제공해야 합니다.

#!/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;

관련 정보