سؤال

لدي دليل مليء بالملفات وأحتاج إلى سحب الرؤوس والتذييلات منها.جميعها ذات أطوال متغيرة، لذا فإن استخدام الرأس أو الذيل لن ينجح.يحتوي كل ملف على سطر يمكنني البحث عنه، لكنني لا أريد تضمين السطر في النتائج.

عادة

*** Start (more text here)

وينتهي ب

*** Finish (more text here)

أريد أن تظل أسماء الملفات كما هي، لذا أحتاج إلى الكتابة فوق النسخ الأصلية، أو الكتابة إلى دليل مختلف وسأقوم بالكتابة فوقها بنفسي.

أوه نعم، إنه موجود على خادم Linux بالطبع، لذا لدي Perl وsed وawk وgrep وما إلى ذلك.

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

المحلول

الوجه بالتخبط! ".." المشغل.

# flip-flop.pl
use strict;
use warnings;

my $start  = qr/^\*\*\* Start/;
my $finish = qr/^\*\*\* Finish/;

while ( <> ) {
    if ( /$start/ .. /$finish/ ) {
        next  if /$start/ or /$finish/;
        print $_;
    }
}

وU ويمكن بعد ذلك استخدام رمز التبديل بيرل -i لتحديث ملف الخاص بك (ق) مثل ذلك .....

 $ perl -i'copy_*' flip-flop.pl data.txt 

... والذي يتغير data.txt لكن يجعل نسخة مسبقا باسم "copy_data.txt".

نصائح أخرى

وcoreutils GNU هم صديقك ...

csplit inputfile %^\*\*\* Start%1 /^\*\*\* Finish/ %% {*}

وهذا ينتج الملف المطلوب كما xx00. يمكنك تغيير هذا السلوك من خلال --prefix الخيارات، --suffix، و--digits، ولكن انظر في دليل لنفسك. منذ تم تصميم csplit لإنتاج عدد من الملفات، فإنه ليس من الممكن أن ينتج ملف بدون لاحقة، لذلك سيكون لديك لتفعل الكتابة يدويا أو من خلال برنامج نصي:

csplit $1 %^\*\*\* Start%1 /^\*\*\* Finish/ %% {*}
mv -f xx00 $1

واضافة الحلقات كما تريدها.

للحصول على header:

cat yourFileHere | awk '{if (d > 0) print $0} /.*Start.*/ {d = 1}'

للحصول على تذييل:

cat yourFileHere | awk '/.*Finish.*/ {d = 1} {if (d < 1) print $0}'

للحصول على الملف من رأس إلى تذييل كما تريد:

cat yourFileHere | awk '/.*Start.*/ {d = 1; next} /.*Finish.*/ {d = 0; next} {if (d > 0) print $0}'

هناك طريقة أخرى، باستخدام الأمر csplit، يجب عليك تجربة شيء مثل:

csplit yourFileHere /Start/ /Finish/

وقم بفحص الملفات المسماة 'xxNN' حيث يقوم NN بتشغيل الرقم، وألق نظرة عليها أيضًا com.csplit manpage.

وربما؟ البداية الى النهاية مع عدم الحذف.

$ sed -i '/^\*\*\* Start/,/^\*\*\* Finish/d!' *

وأو ... أقل متأكدا من ذلك ... ولكن، إذا كان يعمل، يجب إزالة خطوط البداية والنهاية أيضا:

$ sed -i -e '/./,/^\*\*\* Start/d' -e '/^\*\*\* Finish/,/./d' *

وقد تعتمد d! على بناء sed لديك - ولست متأكدا
. وكتبت ان كليا على (وربما الفقيرة) الذاكرة.

وA بيرل سريعة الإختراق، لم تختبر. أنا لست بطلاقة بما فيه الكفاية في الحوار الاقتصادي الاستراتيجي أو AWK للحصول على هذا التأثير معهم، ولكن أود أن تكون مهتمة في كيف يمكن أن يتم ذلك.

#!/usr/bin/perl -w
use strict;
use Tie::File;
my $Filename=shift;  
tie my @File, 'Tie::File', $Filename or die "could not access $Filename.\n";  
while (shift @File !~ /^\*\*\* Start/) {};  
while (pop @File !~ /^\*\*\* Finish/) {};  
untie @File;  

وبعض من الأمثلة في perlfaq5: كيف يمكنني تغيير أو حذف أو إدراج سطر في ملف، أو إلحاق إلى بداية الملف؟ قد تساعد. سيكون لديك لتكييفها مع الوضع الخاص بك. أيضا، الوجه بالتخبط مشغل الجواب ليون هي الطريقة الاصطلاحية للقيام بذلك في بيرل، على الرغم من أنك لم يكن لديك لتعديل الملف في المكان المناسب لاستخدامها.

وحل بيرل أن الكتابة فوق الملف الأصلي.

#!/usr/bin/perl -ni
if(my $num = /^\*\*\* Start/ .. /^\*\*\* Finish/) {
    print if $num != 1 and $num + 0 eq $num;
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top