سؤال

لدي ملف يحتوي على هذا النوع من المسارات:

C:\bad\foo.c
C:\good\foo.c
C:\good\bar\foo.c
C:\good\bar\[variable subdir count]\foo.c

وأريد الحصول على الملف التالي:

C:\bad\foo.c
C:/good/foo.c
C:/good/bar/foo.c
C:/good/bar/[variable subdir count]/foo.c

لاحظ أنه لا ينبغي تعديل المسار غير المطابق.

أعرف كيفية القيام بذلك باستخدام sed لعدد ثابت من subdir، ولكن الرقم المتغير يسبب لي مشكلة.في الواقع، أود أن استخدام الكثير s/x/y/ التعبيرات (ما يصل إلى أقصى عمق ...ليست أنيقة جدًا).

قد يكون الأمر محرجًا، لكن هذا النوع من السحر يتجاوز مهاراتي.

لمعلوماتك، أحتاج إلى هذه الخدعة لتصحيح بعض ملفات gcov الثنائية على منصة cygwin.


أنا أتعامل مع الملفات الثنائية.لذلك، قد يكون لدي النوع التالي من البيانات:

bindata\bindata%bindataC:\good\foo.c

والتي ينبغي ترجمتها على النحو التالي:

bindata\bindata%bindataC:/good/foo.c

الأول \ لا يجب ترجمتها، رغم أنها على نفس الخط.

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

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

المحلول

sed -e '/^C:\\good/ s/\\/\//g' input_file.txt

نصائح أخرى

أنصحك بالنظر في cygpath الأداة المساعدة، التي تحول أسماء المسارات من تنسيق إلى آخر.على سبيل المثال على جهازي:

$ cygpath `pwd`
/home/jericson

$ cygpath -w `pwd`
D:\root\home\jericson

$ cygpath -m `pwd`
D:/root/home/jericson

إليك تطبيق Perl لما طلبته:

$ echo 'C:\bad\foo.c
C:\good\foo.c
C:\good\bar\foo.c
C:\good\bar\[variable subdir count]\foo.c' | perl -pe 's|\\|/|g if /good/'
C:\bad\foo.c
C:/good/foo.c
C:/good/bar/foo.c
C:/good/bar/[variable subdir count]/foo.c

إنه يعمل مباشرة مع السلسلة، لذلك سيعمل في أي مكان.يمكنك الجمع بينه وبين cygpath, ، ولكنه يعمل فقط على الأجهزة التي لها هذا المسار:

perl -pe '$_ = `cygpath -m $_` if /good/'

(نظرًا لعدم وجود C:\good على جهازي، أحصل على إخراج مثل C:goodfoo.c.إذا كنت تستخدم مسارًا حقيقيًا على جهازك، فيجب أن يعمل بشكل صحيح.)

تريد الاستبدال"/"للجميع"\"ولكن فقط على الأسطر التي تطابق مسار الدليل الجيد.سيسمح لك كل من sed و awk بالقيام بذلك من خلال وجود تعبير LHS (مطابق) يختار فقط الخطوط ذات المسار الصحيح.

سيبدو البرنامج النصي sed التافه للقيام بذلك كما يلي:

/[Cc]:\\good/ s/\\/\//g

للحصول على ملف:

c:\bad\foo
c:\bad\foo\bar
c:\good\foo
c:\good\foo\bar

سوف تحصل على الإخراج أدناه:

c:\bad\foo
c:\bad\foo\bar
c:/good/foo
c:/good/foo/bar

إليك كيف سأفعل ذلك في awk:

# fixpaths.awk
/C:\\good/ {
   gsub(/\\/,"/",$1);
   print $1 >> outfile;
}

ثم قم بتشغيله باستخدام الأمر:

awk -f fixpaths.awk paths.txt; mv outfile paths.txt

أو ببعض المساعدة من Good ol 'Bash:

#!/bin/bash

cat file | while read LINE
do
        if <bad_condition>
        then
                echo "$LINE" >> newfile
        else
                echo "$LINE" | sed -e "s/\\/\//g" >> newfile
        fi
done

جرب هذا

sed -re '/\\good\\/ s/\\/\//g' temp.txt

أو هذا

awk -F"\\" '{if($2=="good"){OFS="\/"; $1=$1;} print $0}' temp.txt

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top