wstaw ciąg między dwoma wzorami

2

Chciałbym zmienić plik o nazwie takiej jak:

d1-a2_A1_B1.txt
abcd_A90_B2.txt

gdzie chcę wstawić _FOOmiędzy pierwszy, _A[0-9]\+a _B[0-9]więc nazwy plików stają się

d1-a2_A1_FOO_B1.txt
abcd_A90_FOO_B2.txt

Ale moje wyrażenie regularne nie działa:

for f in $(ls); do mv $f \`echo $f | sed -e s/\(.*_A[0-9]\+\)\(_B[0-9].*\)/$1_FOO$2/\`; done

Próbowałem z jednym ciągiem:

echo abcd_A90_B2.txt | sed -e s/\(.*_A[0-9]\+\)\(_B[0-9].*\)/$1_FOO$2/

OK: zadziałało:

echo abcd_A90_B2.txt | sed -e 's/\(_A[0-9]\+\)\(_B[0-9]\)/\1_FOO\2/'
użytkownik2783615
źródło
Twoje posty zostaną znacznie ulepszone dzięki lepszemu formatowaniu. Oto strona pomocy dotycząca formatowania . Zredagowałbym to sam, ale czeka mnie kolejna edycja, więc nie mogę.
Tom Zych

Odpowiedzi:

0
  • Dodaj -ropcję do sed(aby użyć rozszerzonych wyrażeń regularnych; normalnie nie rozumie +).
  • Umieść swój sedskrypt w cudzysłowie (najlepiej pojedyncze).
  • Zmień $1iw $2swoim skrypcie na \1i \2:

    sed -re ' s /(._ A [0-9] +) (_ B [0-9].) / \ 1_FOO \ 2 / '

Również,

  • Dla jasności możesz chcieć zmienić `…`na $(…)- zobacz to , to i tamto - tj. Obsługuj w echo | sedtaki sam sposób, jak to robisz ls.
  • Lepiej powiedzieć for f in *(zamiast for f in $(ls)).
  • Powinieneś zacytować odwołania do zmiennych powłoki (np. echo "$f"), Chyba że masz dobry powód, aby tego nie robić i jesteś pewien, że wiesz, co robisz.
Scott
źródło
Próbowałem, ale nie działałem: echo abcd_A90_B2.txt | sed -e 's /(._ A [0-9] +) (_ B [0-9].) / $ 1_FOO $ 2 /', które nie zmieniły abcd_A90_B2.txt
user2783615
OK, poprawiłem swoją odpowiedź.
Scott
0

Możesz uniknąć używania sed i innych manipulacji ciągiem, używając mmv:

$ mmv -m -n  '*_A*_B*.txt' '#1_A#2_FOO_B#3.txt'
abcd_A90_B2.txt -> abcd_A90_FOO_B2.txt
d1-a2_A1_B1.txt -> d1-a2_A1_FOO_B1.txt

(Pomiń -nlub zamień na, -vaby faktycznie zmienić nazwę plików, gdy potwierdzisz, że wszystkie pliki są dopasowane i zmieniają nazwy zgodnie z potrzebami.

Bram
źródło