سؤال كيف يمكنني حذف U + 200B (مساحة صفر العرض) باستخدام sed


لدي ملف كبير جدًا يحتوي على مسافات صفرية العرض منتشرة في جميع أنحاء. يستغرق الأمر وقتًا طويلاً لفتحه وتعديله باستخدام vi لذلك أود حذف جميع أمثلة الحرف باستخدام sed. المشكلة هي ، لا أستطيع معرفة كيفية مطابقة شخصية! لقد حاولت استخدام \u200B، \x{200b}. أيه أفكار؟

أنا أدير CentOS 5 إذا كان ذلك يساعد على الإطلاق.


14
2017-11-04 20:33


الأصل


هل تدعم نسختك من sed ترميز Unicode الذي تم ترميز الملف به؟ إن لم يكن هناك ربما لا توجد طريقة جيدة للقيام بذلك بشكل صحيح مع [س] ، وكنت أفضل استخدام سكريبت بيثون أو شيء من هذا القبيل ... - JanC
JanC - في الواقع ، لقد ذهبت مع بيثون. يتم ترميز الملف باستخدام utf8 ، ويبدو معيارًا كافيًا بحيث يمكن لأي شيء معالجته. لقد أضفت البرنامج النصي لبيثون أدناه ، في حال كانت مفيدة لأي شخص. - thetaiko


الأجوبة:


يبدو هذا عمل بالنسبة لي:

sed 's/\xe2\x80\x8b//g' inputfile

برهنة:

$ /usr/bin/printf 'X\u200bY\u200bZ' | hexdump -C
00000000  58 e2 80 8b 59 e2 80 8b  5a                       |X...Y...Z|
$ /usr/bin/printf 'X\u200bY\u200bZ' | sed 's/\xe2\x80\x8b//g' | hexdump -C
00000000  58 59 5a                                          |XYZ|

تصحيح:

تعتمد جزئيًا على إجابة جيل:

tr -d $(/usr/bin/printf "\u200b") < inputfile

11
2017-11-04 22:23



مثالي - هذا هو بالضبط ما كنت أبحث عنه. في الحقيقة ، لاحظت أن نفس المجموعة من الشخصيات\xe2\x80\x8b) عند النظر إلى بعض سلاسل العينات في Python. شكرا لكم! - thetaiko


لا يبدو سلوك جنو سيد مع UTF-8 محددًا جيدًا. تجريبياً ، يمكنك جعله استبدال وحدات البايت الخاصة بتمثيل UTF-8:

<old sed 's/\xe2\x80\e8b//g' >new

بدلاً من ذلك ، يمكنك كتابة الحرف في shell واستخدام أي من الأوامر القياسية في لغة UTF-8:

<old tr -d '​' >new
<old sed 's/​//g' >new

في zsh ، يمكنك أيضًا إدخال الحرف من خلال تسلسل هروب:

<old tr -d $'\u200B' >new

4
2017-11-04 22:50



اعتبارًا من Bash 4.2 ، يتم دعم تسلسل Unicode بواسطة echo -e، printf سلاسل التنسيق و ANSI سلاسل مقتبسة (على سبيل المثال echo -e '\u1E4F'، printf '\u01DD %s\n' 'X'، mkdir $'\u0250) - Dennis Williamson


حسنا ، ما لم يكن أي شخص لديه أي أفكار حول كيفية الحصول عليها sed للقيام بذلك (التي ما زلت مهتمة ، بالمناسبة) بيثون لها لإنقاذ ...

import sys, re
pattern = re.compile(u"\u200b")
f = open(sys.stdin, "rb")
for line in f:
    a = pattern.sub("", line.decode("utf8"))
    print a.encode("utf8"),
f.close()

0
2017-11-04 21:41



إذا كنت ستصل إلى المدافع الكبيرة ، فكيف أبسط بكثير perl -C -pe 's/\x{200B}//g'؟ - Gilles
+1 إلى Gilles التي تعمل أيضًا على نظام التشغيل Mac OSX. perl -C -pi.bak -e 's/\x{200B}//g' yourfile النتائج في yourfile الثابتة والنسخ الاحتياطي في yourfile.bak - MarkHu