ข้อผิดพลาด RE: ลำดับไบต์ที่ผิดกฎหมายบน Mac OS X


184

ฉันกำลังพยายามแทนที่สตริงใน Makefile บน Mac OS X สำหรับการคอมไพล์ข้ามเป็น iOS สตริงมีเครื่องหมายคำพูดคู่ฝังอยู่ คำสั่งคือ:

sed -i "" 's|"iphoneos-cross","llvm-gcc:-O3|"iphoneos-cross","clang:-Os|g' Configure

และข้อผิดพลาดคือ:

sed: RE error: illegal byte sequence

ฉันได้ลองใช้เครื่องหมายคำพูดคู่เครื่องหมายจุลภาคขีดคั่นและเครื่องหมายทวิภาคโดยไม่มีความสุข ตัวอย่างเช่น:

sed -i "" 's|\"iphoneos-cross\"\,\"llvm-gcc\:\-O3|\"iphoneos-cross\"\,\"clang\:\-Os|g' Configure

ฉันมีเวลาสักครู่ในการดีบักปัญหา ไม่มีใครรู้วิธีการsedพิมพ์ตำแหน่งของลำดับไบต์ที่ผิดกฎหมายหรือไม่ หรือใครรู้ว่าลำดับไบต์ที่ผิดกฎหมายคืออะไร?


2
ลำดับไบต์ที่ผิดกฎหมายดูเหมือนสิ่งที่คุณได้รับเมื่อป้อน ASCII 8 บิตเป็นสิ่งที่คาดว่า utf-8
Klas Lindbäck

36
คุณลองได้ไหม:LC_CTYPE=C && LANG=C && sed command
anubhava

5
ขอบคุณผู้คน มันคือLANGสิ่งที่ เฮ้อ ....
jww

3
@ user2719058: BSD sed(ตามที่ใช้บน OS X) ต้องการ-i ''(แยกสตริงตัวเลือกอาร์กิวเมนต์ว่าง) สำหรับการอัปเดตแบบแทนที่โดยไม่มีไฟล์สำรอง ด้วย GNU ทำงานได้ด้วยตัวเองsedเท่านั้น-i- ดูstackoverflow.com/a/40777793/45375
mklement0

1
บวกหนึ่งสำหรับสิ่ง LANG ความเศร้าโศกที่ดีนั้นไม่ชัดเจนไม่ชัดเจนและยากต่อการวิจัย
Spudley

คำตอบ:


300

คำสั่งตัวอย่างที่แสดงอาการ: sed 's/./@/' <<<$'\xfc'ล้มเหลวเนื่องจากไบต์0xfcไม่ใช่อักขระ UTF-8 ที่ถูกต้อง
โปรดทราบว่าในทางตรงกันข้ามGNU sed (Linux แต่ยังสามารถติดตั้งบน macOS) จะส่งไบต์ที่ไม่ถูกต้องผ่านโดยไม่รายงานข้อผิดพลาด

การใช้คำตอบที่ยอมรับก่อนหน้านี้เป็นตัวเลือกหากคุณไม่สนใจที่จะสูญเสียการสนับสนุนสถานที่ที่แท้จริงของคุณ (หากคุณใช้ระบบของสหรัฐอเมริกาและคุณไม่จำเป็นต้องจัดการกับตัวละครต่างประเทศนั่นอาจจะใช้ได้)

อย่างไรก็ตามเอฟเฟกต์เดียวกันสามารถมีad-hocสำหรับคำสั่งเดียวเท่านั้น :

LC_ALL=C sed -i "" 's|"iphoneos-cross","llvm-gcc:-O3|"iphoneos-cross","clang:-Os|g' Configure

หมายเหตุ: สิ่งที่สำคัญคือการที่มีประสิทธิภาพใน LC_CTYPEการตั้งค่าCเพื่อLC_CTYPE=C sed ...จะได้ตามปกตินอกจากนี้ยังมีการทำงาน แต่ถ้าLC_ALLเกิดขึ้นจะเป็นชุด (อย่างอื่นที่ไม่ใช่C) ก็จะแทนที่แต่ละLC_*ตัวแปร -category LC_CTYPEเช่น LC_ALLดังนั้นวิธีการที่มีประสิทธิภาพที่สุดคือการตั้งค่า

อย่างไรก็ตามการตั้งค่า (อย่างมีประสิทธิภาพ) LC_CTYPEเพื่อใช้กับCสตริงราวกับว่าแต่ละไบต์เป็นอักขระของตัวเอง ( ไม่มีการตีความตามกฎการเข้ารหัส) โดยไม่คำนึงถึง - การเข้ารหัสแบบหลายไบต์ตามความต้องการ - การเข้ารหัส UTF-8ที่ OS X ใช้โดยค่าเริ่มต้น ที่ตัวละครต่างประเทศมีการเข้ารหัสสัญลักษณ์

สรุป: การตั้งค่าLC_CTYPEเพื่อCสาเหตุเปลือกและระบบสาธารณูปโภคที่จะรู้จักตัวอักษรภาษาอังกฤษขั้นพื้นฐานเป็นตัวอักษร (คนที่อยู่ในช่วง ASCII 7 บิต) เพื่อให้ตัวอักษรต่างประเทศ จะไม่ถือว่าเป็นตัวอักษรซึ่งทำให้ตัวอย่างเช่นการแปลงด้านบน / ตัวพิมพ์เล็กล้มเหลว

อีกครั้งนี้อาจจะดีถ้าคุณไม่จำเป็นต้องตรงกับตัวอักษรสัญลักษณ์เข้ารหัสเช่นéและก็ต้องการที่จะผ่านตัวละครดังกล่าวผ่าน

หากนี่ไม่เพียงพอและ / หรือคุณต้องการเข้าใจสาเหตุของข้อผิดพลาดเดิม (รวมถึงการกำหนดว่าไบต์อินพุตใดที่ทำให้เกิดปัญหา) และทำการแปลงการแปลงตามความต้องการอ่านด้านล่าง


ปัญหาคือการเข้ารหัสไฟล์อินพุตไม่ตรงกับเชลล์
โดยเฉพาะอย่างยิ่งแฟ้มใส่มีอักขระที่เข้ารหัสในทางที่ไม่ถูกต้อง UTF-8 (ตาม @Klas Lindback ที่ระบุไว้ในความคิดเห็น) - นั่นคือสิ่งที่เป็นข้อผิดพลาดคือการพยายามที่จะพูดโดยsedinvalid byte sequence

ส่วนใหญ่แล้วไฟล์อินพุตของคุณใช้การเข้ารหัสไบต์เดียว 8 บิตเช่นที่ISO-8859-1ใช้บ่อยในการเข้ารหัสภาษา "ยุโรปตะวันตก"

ตัวอย่าง:

ตัวอักษรสำเนียงàมี Unicode codepoint 0xE0(224) - ISO-8859-1เช่นเดียวกับใน อย่างไรก็ตามเนื่องจากธรรมชาติของUTF-8เข้ารหัสนี้ codepoint เดียวจะแสดงเป็น2ไบต์ - 0xC3 0xA0ในขณะที่พยายามที่จะผ่านbyte เดียว 0xE0คือไม่ถูกต้องภายใต้ UTF-8

ต่อไปนี้คือการสาธิตปัญหาโดยใช้สตริงที่voilàเข้ารหัสISO-8859-1ด้วยโดยàแสดงเป็นหนึ่งไบต์ (ผ่านสตริงทุบตี ANSI-C- ที่ยกมา ( $'...') ที่ใช้\x{e0}ในการสร้างไบต์):

โปรดทราบว่าsedคำสั่งนั้นไม่มีประสิทธิภาพในการส่งผ่านอินพุต แต่เราจำเป็นต้องใช้เพื่อกระตุ้นข้อผิดพลาด:

  # -> 'illegal byte sequence': byte 0xE0 is not a valid char.
sed 's/.*/&/' <<<$'voil\x{e0}'

หากต้องการเพิกเฉยต่อปัญหาLCTYPE=Cวิธีการข้างต้นสามารถใช้ได้:

  # No error, bytes are passed through ('á' will render as '?', though).
LC_CTYPE=C sed 's/.*/&/' <<<$'voil\x{e0}'

หากคุณต้องการตรวจสอบว่าส่วนใดของอินพุตที่ทำให้เกิดปัญหาลองทำสิ่งต่อไปนี้:

  # Convert bytes in the 8-bit range (high bit set) to hex. representation.
  # -> 'voil\x{e0}'
iconv -f ASCII --byte-subst='\x{%02x}' <<<$'voil\x{e0}'

เอาต์พุตจะแสดงไบต์ทั้งหมดที่มีชุดบิตสูง (ไบต์ที่เกินช่วง ASCII 7 บิต) ในรูปแบบเลขฐานสิบหก (อย่างไรก็ตามโปรดทราบว่ายังรวมถึงการเข้ารหัส multibyte UTF-8 ที่เข้ารหัสอย่างถูกต้อง - จำเป็นต้องใช้วิธีการที่ซับซ้อนยิ่งขึ้นในการระบุไบต์ที่ไม่ถูกต้องใน UTF-8 โดยเฉพาะ)


ทำการแปลงการเข้ารหัสตามคำขอ :

ยูทิลิตี้มาตรฐานiconvสามารถใช้ในการแปลงเป็น ( -t) และ / หรือจากการ-fเข้ารหัส( ); iconv -lแสดงรายการที่รองรับทั้งหมด

ตัวอย่าง:

แปลงจากISO-8859-1การเข้ารหัสที่มีผลบังคับใช้ในเชลล์ (อิงLC_CTYPEซึ่งเป็นUTF-8เบสโดยค่าเริ่มต้น) อาคารในตัวอย่างข้างต้น:

  # Converts to UTF-8; output renders correctly as 'voilà'
sed 's/.*/&/' <<<"$(iconv -f ISO-8859-1 <<<$'voil\x{e0}')"

โปรดทราบว่าการแปลงนี้ช่วยให้คุณจับคู่อักขระต่างประเทศได้อย่างถูกต้อง :

  # Correctly matches 'à' and replaces it with 'ü': -> 'voilü'
sed 's/à/ü/' <<<"$(iconv -f ISO-8859-1 <<<$'voil\x{e0}')"

ในการแปลงอินพุต BACK เป็นISO-8859-1หลังการประมวลผลเพียงไพพ์ผลลัพธ์ไปยังiconvคำสั่งอื่น:

sed 's/à/ü/' <<<"$(iconv -f ISO-8859-1 <<<$'voil\x{e0}')" | iconv -t ISO-8859-1

4
ฉันว่านี่เป็นตัวเลือกที่ดีกว่ามาก ก่อนอื่นฉันไม่ต้องการสูญเสียการสนับสนุนหลายภาษาใน Terminal ทั้งหมด ประการที่สองคำตอบที่ได้รับการยอมรับรู้สึกเหมือนเป็นทางออกทั่วโลกสำหรับปัญหาในท้องถิ่น - สิ่งที่ต้องหลีกเลี่ยง
อเล็กซ์

ฉันมีการปรับแต่งเล็กน้อยนี้ ฉันขอขอบคุณข้อเสนอแนะ stackoverflow.com/a/35046218/9636
Heath Borders

LC_CTYPE=C sed 's/.*/&/' <<<$'voil\x{e0}'พิมพ์sed: RE error: illegal byte sequenceสำหรับฉันในเซีย echo $LC_ALLเอาต์พุตen_US.UTF-8FWIW
ahcox

1
@ahcox: ใช่เพราะการตั้งค่าLC_ALL แทนที่LC_*ตัวแปรอื่น ๆ ทั้งหมดรวมถึงLC_CTYPEตามที่อธิบายไว้ในคำตอบ
mklement0

2
@ mklement0 เจ๋งผลงานนี้: "LC_ALL = C sed 's /.*/&/' <<< $ 'voil \ x {e0}'" คำนำหน้าอธิบายไว้ที่นี่สำหรับเพื่อนของฉันที่ไม่รู้เรื่องไม่ตั้งใจ: pubs.opengroup.org/onlinepubs/7908799/xbd/envvar.html
ahcox

142

เพิ่มบรรทัดต่อไปนี้ของคุณ~/.bash_profileหรือ~/.zshrcไฟล์ (s)

export LC_CTYPE=C 
export LANG=C

29
ใช้งานได้จริง แต่คุณช่วยอธิบายได้ไหมว่าทำไม
Hoang Pham

11
@ HoangPham: การตั้งค่าLC_CTYPEเพื่อCทำให้แต่ละไบต์ในสตริงเป็นอักขระของตัวเองโดยไม่ต้องใช้กฎการเข้ารหัสใด ๆ เนื่องจากการละเมิดกฎการเข้ารหัส (UTF-8) ทำให้เกิดปัญหาเดิมซึ่งทำให้ปัญหาหายไป อย่างไรก็ตามราคาที่คุณจ่ายคือเชลล์และยูทิลิตีจะจำตัวอักษรภาษาอังกฤษพื้นฐานเท่านั้น (ตัวที่อยู่ในช่วง ASCII 7 บิต) เป็นตัวอักษร ดูคำตอบของฉันมากขึ้น
mklement0

6
การตั้งค่านี้อย่างถาวรในไฟล์เริ่มต้นของเชลล์จะปิดใช้งานพฤติกรรมที่มีประโยชน์มากมาย คุณต้องการใส่สิ่งนี้ในคำสั่งเฉพาะบุคคลซึ่งจำเป็นต้องใช้มันอย่างแน่นอน
tripleee

4
อันตรายเกินไปอาจทำให้เกิดผลที่ไม่คาดคิด หนึ่งสามารถใช้LC_CTYPE=C sed …คือเฉพาะในคำสั่ง sed
Yongwei Wu

2
นี่จะปิดใช้งานการสนับสนุนอักขระ Unicode ในเชลล์ของคุณอย่างสมบูรณ์ ลาก่อนอิโมจิตัวละครวาดเส้นแฟนซีตัวอักษรพร้อมสำเนียง, .... ดีกว่ามากที่จะตั้งค่านี้สำหรับคำสั่ง sed เท่านั้นตามที่อธิบายไว้ในคำตอบอื่น ๆ
asmeurer

6

วิธีแก้ปัญหาของฉันใช้ Perl:

find . -type f -print0 | xargs -0 perl -pi -e 's/was/now/g'

อันนี้ใช้งานได้ดี และฉันก็ไม่มีข้อผิดพลาดใด ๆ ในการหลบหลีกตัวละครพิเศษ คนก่อนหน้านี้ทำให้ฉันมีปัญหาเช่น "sed: RE ข้อผิดพลาด: ลำดับไบต์ที่ผิดกฎหมาย" หรือ sed: 1: "path_to_file": รหัสคำสั่งที่ไม่ถูกต้อง
JMags1632

3

คำตอบของ mklement0นั้นยอดเยี่ยม แต่ฉันมีการปรับแต่งเล็กน้อย

ดูเหมือนว่าเป็นความคิดที่ดีที่จะระบุการbashเข้ารหัสของเมื่อใช้iconvอย่างชัดเจน นอกจากนี้เราควรย่อหน้าเครื่องหมายสั่งไบต์ ( แม้ว่ามาตรฐาน Unicode ไม่แนะนำ ) เพราะอาจจะมีความสับสนที่ถูกต้องระหว่าง UTF-8 และ ASCII โดยไม่ต้องมีเครื่องหมายสั่งไบต์ น่าเสียดายที่iconvไม่ได้ทำเครื่องหมายสั่งแบบไบต์ล่วงหน้าไว้เมื่อคุณระบุ endianness ( UTF-16BEหรือUTF-16LE) อย่างชัดเจนดังนั้นเราจึงจำเป็นต้องใช้UTF-16ซึ่งใช้ endianness เฉพาะแพลตฟอร์มแล้วใช้file --mime-encodingเพื่อค้นหา endianness ที่แท้จริงที่iconvใช้

(ฉันเป็นตัวพิมพ์ใหญ่การเข้ารหัสทั้งหมดของฉันเพราะเมื่อคุณแสดงรายการiconvการเข้ารหัสที่สนับสนุนทั้งหมดด้วยiconv -lพวกเขาจะเป็นตัวพิมพ์ใหญ่ทั้งหมด)

# Find out MY_FILE's encoding
# We'll convert back to this at the end
FILE_ENCODING="$( file --brief --mime-encoding MY_FILE )"
# Find out bash's encoding, with which we should encode
# MY_FILE so sed doesn't fail with 
# sed: RE error: illegal byte sequence
BASH_ENCODING="$( locale charmap | tr [:lower:] [:upper:] )"
# Convert to UTF-16 (unknown endianness) so iconv ensures
# we have a byte-order mark
iconv -f "$FILE_ENCODING" -t UTF-16 MY_FILE > MY_FILE.utf16_encoding
# Whether we're using UTF-16BE or UTF-16LE
UTF16_ENCODING="$( file --brief --mime-encoding MY_FILE.utf16_encoding )"
# Now we can use MY_FILE.bash_encoding with sed
iconv -f "$UTF16_ENCODING" -t "$BASH_ENCODING" MY_FILE.utf16_encoding > MY_FILE.bash_encoding
# sed!
sed 's/.*/&/' MY_FILE.bash_encoding > MY_FILE_SEDDED.bash_encoding
# now convert MY_FILE_SEDDED.bash_encoding back to its original encoding
iconv -f "$BASH_ENCODING" -t "$FILE_ENCODING" MY_FILE_SEDDED.bash_encoding > MY_FILE_SEDDED
# Now MY_FILE_SEDDED has been processed by sed, and is in the same encoding as MY_FILE

1
++ สำหรับเทคนิคที่เป็นประโยชน์โดยเฉพาะอย่างยิ่งfile -b --mime-encodingสำหรับการค้นพบและการรายงานการเข้ารหัสของไฟล์ อย่างไรก็ตามมีบางแง่มุมที่ควรกล่าวถึงซึ่งฉันจะทำในความคิดเห็นแยกต่างหาก
mklement0

2
ฉันคิดว่ามันปลอดภัยที่จะบอกว่าโลกของ Unix ได้สวมกอด UTF-8 ณ จุดนี้: โดยปกติแล้วLC_CTYPEค่าเริ่มต้น<lang_region>.UTF-8ดังนั้นไฟล์ใด ๆ ที่ไม่มี BOM (เครื่องหมายคำสั่งไบต์) จึงตีความว่าเป็นไฟล์ UTF-8 มันเป็นเพียงในโลกของWindowsที่ใช้pseudo-BOM 0xef 0xbb 0xffเท่านั้น ตามคำนิยาม UTF-8 ไม่ต้องการ BOM และไม่แนะนำ (ตามที่คุณระบุ); นอกโลกของ Windows นี้หลอก BOM ทำให้เกิดสิ่งที่จะหยุดพัก
mklement0

2
ตอบUnfortunately, iconv doesn't prepend a byte-order mark when you explicitly specify an endianness (UTF-16BE or UTF-16LE): นั่นคือจากการออกแบบ: หากคุณระบุ endianness อย่างชัดเจนไม่จำเป็นต้องสะท้อนผ่าน BOM ดังนั้นจึงไม่มีการเพิ่ม
mklement0

1
Re LC_*/ LANGตัวแปร: bash,, kshและzsh(อาจเป็นอย่างอื่น, แต่ไม่ dash ) ทำตามการเข้ารหัสตัวอักษร; ตรวจสอบในเปลือกเหมือน POSIX ด้วยสถานที่ตาม UTF-8 ด้วยv='ä'; echo "${#v}": เชลล์ทราบ UTF-8 ควรรายงาน1; เช่นควรจดจำลำดับหลายไบต์ä( 0xc3 0xa4) เป็นอักขระตัวเดียว บางทีอาจจะสำคัญมากขึ้น แต่ที่: สาธารณูปโภคมาตรฐาน ( sed, awk, cut, ... ) ยังจะต้องมีสถานที่ / การเข้ารหัสทราบและในขณะที่ส่วนใหญ่ของพวกเขาในการที่ทันสมัยยูนิกซ์เช่นแพลตฟอร์มจะมีข้อยกเว้นเช่นawkใน OSX, และcutบน Linux
mklement0

1
เป็นที่น่ายกย่องที่fileรู้จัก UTF-8 pseudo-BOM แต่ปัญหาคือยูทิลิตี้ Unix ส่วนใหญ่ที่ประมวลผลไฟล์ไม่ได้และมักจะผิดพลาดหรือทำงานผิดปกติอย่างน้อยที่สุด หากไม่มี BOM ให้fileระบุไฟล์ all-7-bit เป็น ASCII อย่างถูกต้องและไฟล์ที่มีอักขระหลายไบต์ UTF-8 ที่ถูกต้องเป็น UTF-8 ความสวยงามของ UTF-8 คือมันเป็นsupersetของ ASCII: ไฟล์ ASCII ที่ถูกต้องใด ๆ คือนิยามไฟล์ UTF-8 ที่ถูกต้อง (แต่ไม่ใช่ในทางกลับกัน); มันปลอดภัยอย่างสมบูรณ์แบบในการจัดการไฟล์ ASCII ในรูปแบบ UTF-8 (ซึ่งในทางเทคนิคแล้วมันเกิดขึ้นที่ไม่มีตัวอักษรแบบหลายไบต์)
mklement0

2

คุณเพียงแค่ต้องไพพ์คำสั่งiconvก่อนคำสั่งsed ตัวอย่างด้วยอินพุต file.txt:

iconv -f ISO-8859-1 -t UTF8-MAC file.txt | sed 's / something / àéèêçùû / g' | .....

-fตัวเลือกคือชุดรหัส 'จาก' และตัวเลือก -t คือการแปลงชุดรหัส 'เป็น'

ระวังตัวพิมพ์เล็กหน้าเว็บจะแสดงตัวพิมพ์เล็กเช่น <charset = iso-8859-1 "/> และiconvใช้ตัวพิมพ์ใหญ่คุณมีรายการของชุดไอคอนที่รองรับiconvในระบบของคุณด้วยคำสั่งiconv -l

UTF8-MACเป็นชุดรหัส Mac OS ที่ทันสมัยสำหรับการแปลง


ดูที่iconv และชื่อชุดอักขระในรายการส่งเมล iconv
jww

1

ไม่มีใครรู้วิธีที่จะได้ใจที่จะพิมพ์ตำแหน่งของลำดับไบต์ที่ผิดกฎหมาย? หรือใครรู้ว่าลำดับไบต์ที่ผิดกฎหมายคืออะไร?

$ uname -a
Darwin Adams-iMac 18.7.0 Darwin Kernel Version 18.7.0: Tue Aug 20 16:57:14 PDT 2019; root:xnu-4903.271.2~2/RELEASE_X86_64 x86_64

ผมได้เป็นส่วนหนึ่งของวิธีการที่จะตอบข้างต้นโดยใช้เพียงแค่TR

ฉันมีไฟล์. csv ที่เป็นใบแจ้งยอดบัตรเครดิตและฉันกำลังพยายามนำเข้าลงใน Gnucash ฉันอาศัยอยู่ในสวิตเซอร์แลนด์ดังนั้นฉันต้องจัดการกับคำอย่างซูริค การสงสัยว่า Gnucash ไม่ชอบ "" ในฟิลด์ตัวเลขฉันจึงตัดสินใจแทนที่ทั้งหมด

; ;

กับ

;;

ไปที่นี่:

$ head -3 Auswertungen.csv | tail -1 | sed -e 's/; ;/;;/g'
sed: RE error: illegal byte sequence

ฉันใช้odเพื่อกำจัดแสง: สังเกต 374 ลงครึ่งหนึ่งของเอาต์พุตod -c นี้

$ head -3 Auswertungen.csv | tail -1 | od -c
0000000    1   6   8   7       9   6   1   9       7   1   2   2   ;   5
0000020    4   6   8       8   7   X   X       X   X   X   X       2   6
0000040    6   0   ;   M   Y       N   A   M   E       I   S   X   ;   1
0000060    4   .   0   2   .   2   0   1   9   ;   9   5   5   2       -
0000100        M   i   t   a   r   b   e   i   t   e   r   r   e   s   t
0000120                Z 374   r   i   c   h                            
0000140    C   H   E   ;   R   e   s   t   a   u   r   a   n   t   s   ,
0000160        B   a   r   s   ;   6   .   2   0   ;   C   H   F   ;    
0000200    ;   C   H   F   ;   6   .   2   0   ;       ;   1   5   .   0
0000220    2   .   2   0   1   9  \n                                    
0000227

จากนั้นฉันคิดว่าฉันอาจลองชักชวนtrแทน 374 สำหรับรหัสไบต์ที่ถูกต้อง ดังนั้นก่อนอื่นฉันลองอะไรที่เรียบง่ายซึ่งใช้งานไม่ได้ แต่มีผลข้างเคียงจากการแสดงให้ฉันเห็นว่าไบต์ที่มีปัญหาคือ:

$ head -3 Auswertungen.csv | tail -1 | tr . .  ; echo
tr: Illegal byte sequence
1687 9619 7122;5468 87XX XXXX 2660;MY NAME ISX;14.02.2019;9552 - Mitarbeiterrest   Z

ท่านสามารถเข้าดูTR Bails ที่ตัวละคร 374

การใช้ Perl ดูเหมือนว่าจะหลีกเลี่ยงปัญหานี้

$ head -3 Auswertungen.csv | tail -1 | perl -pne 's/; ;/;;/g'
1687 9619 7122;5468 87XX XXXX 2660;ADAM NEALIS;14.02.2019;9552 - Mitarbeiterrest   Z?rich       CHE;Restaurants, Bars;6.20;CHF;;CHF;6.20;;15.02.2019

0

วิธีแก้ปัญหาของฉันได้รับการใช้ sedGNU ทำงานได้ดีสำหรับวัตถุประสงค์ของฉัน


แท้จริงGNU sedเป็นตัวเลือกถ้าคุณต้องการที่จะไม่สนใจไบต์ที่ไม่ถูกต้องในการสตรีมใส่ (ไม่จำเป็นสำหรับLC_ALL=C sed ...การแก้ปัญหา) เพราะ GNU sedเพียงผ่านไบต์ที่ไม่ถูกต้องผ่านแทนการรายงานข้อผิดพลาด แต่ทราบว่าถ้าคุณต้องการที่จะต้องรับรู้และกระบวนการทั้งหมด อักขระในสตริงอินพุตไม่มีวิธีแก้ไขการเข้ารหัสของอินพุตก่อน (โดยทั่วไปด้วยiconv)
mklement0
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.