كيف يمكنني إنشاء أمر VIM أو VI لحذف جميع النصوص بعد حرف معين لكل سطر في ملف نصي؟

StackOverflow https://stackoverflow.com/questions/448346

  •  19-08-2019
  •  | 
  •  

سؤال

سيناريو:

  • لدي ملف نصي يحتوي على أنبوب (كما في | الشخصية) البيانات المحددة.
  • يمكن أن يكون كل حقل من البيانات في الحقول المحددة للأنابيب ذات طول متغير ، لذلك لن يعمل حساب الأحرف (أو باستخدام نوع من الوظائف الفرعية ... إذا كان ذلك موجودًا في VIM).

هل من الممكن ، باستخدام VIM / VI لحذف جميع البيانات من الأنبوب الثاني إلى نهاية السطر للملف بأكمله؟ هناك حوالي 150،000 سطر ، لذا فإن القيام بذلك يدويًا لن يكون جذابًا لماسوشي ...

على سبيل المثال

قم بتغيير الأسطر التالية من:

1111|random sized text 12345|more random data la la la|1111|abcde
2222|random sized text abcdefghijk|la la la la|2222|defgh
3333|random sized text|more random data|33333|ijklmnop

إلى:

1111|random sized text 12345
2222|random sized text abcdefghijk
3333|random sized text

أنا متأكد من أنه يمكن القيام بذلك بطريقة أو بأخرى ... آمل.

تيا

تحديث: كان يجب أن أذكر أنني أقوم بتشغيل هذا على Windows XP ، لذلك لا يمكنني الوصول إلى بعض أوامر *NIX المذكورة (لم يتم التعرف على القطع على Windows).

هل كانت مفيدة؟

المحلول

:%s/^\v([^|]+\|[^|]+)\|.*$/\1/

نصائح أخرى

يمكنك أيضًا تسجيل ماكرو:

qq02f|Djq

وبعد ذلك ستتمكن من تشغيله مع 100@Q لتشغيل الماكرو على السطر المائة التالي.

تفسير الماكرو:

  • QQ - يبدأ تسجيل الماكرو
  • 0 - انتقل إلى الطابع الأول للخط
  • 2F | - العثور على الحدوث الثاني من | شخصية على الخط
  • د - احذف النص بعد الموضع الحالي إلى نهاية الخط
  • ي - انتقل إلى السطر التالي
  • س - ينتهي تسجيل الماكرو

إذا لم يكن عليك استخدام VIM ، فإن بديل آخر هو أمر UNIX "CUT".

cut -d '|' -f 1-2 file > out.file

مجرد طريقة أخرى لفعل الشيء نفسه:

%s/^\(.\{-}|\)\{2}\zs.*//
%s/^\(.\{-}\zs|\)\{2}.*// " if you want to remove the 2nd pipe as well

هذه المرة ، تتطابق regex مع عدد قليل من الأحرف ( {-}) قدر الإمكان والتي تليها أنبوب ، ومرتين ( {2}) ، يتم تجاهلها (zS) لاستبدال كل ما يلي ( Zس) نص لا شيء.

بدلاً من الاستبدال يمكن للمرء استخدام :normal أمر بتكرار تسلسل من اثنين من أوامر الوضع العادي القفز إلى الثانية | الشخصية وحذف كل شيء آخر حتى نهاية الخط.

:%norm!2f|D

استخدام: أمر لإنشاء أمر مستخدم يمكنك تشغيله بسهولة.

:command -range=% YourNameHere <line1>,<line2>s/^\v([^|]+\|[^|]+)\|.*$/\1/

يمكنك أيضًا القيام بذلك:

:%s/^\([^\|]\+|[^\|]\+\)\|.*$/\1/g

استخدم awk.

awk -F"|" '{$0=$1"|"$2}1' file

لقد وجدت أن VIM ليس رائعًا في التعامل مع الملفات الكبيرة جدًا. لست متأكدًا من حجم ملفك. ربما تعمل Cat و Sed معًا بشكل أفضل.

هنا حل SED:

sed -e 's/^\([^|]*|[^|]*\).*$/\1/'

سيؤدي ذلك إلى تصفية جميع الخطوط في المخزن المؤقت (1 ، $) من خلال القطع للقيام بالمهمة.

:1,$!cut -d '|' -f 1-2

محاولة مع

:.!cut -d '|' -f 1-2

للقيام بذلك فقط على الخط الحالي.

لماذا تستخدم VIM؟

لماذا لا تفعل فقط

cat my_pipe_file | cut -d'|' -f1-2
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top