Linux Centos 6-64

File1.txt имеет несколько строк в этом формате:

/Text1/Text2/Text3:Text4

Как сделать так, чтобы файл Result.txt был со всеми строками следующим образом?

Text2;Text4

: ; ,

Я думал о двух способах сделать это:

  1. Было бы нормально удалить /Text1/ и удалить /Text3 и изменить : by ; ,
  2. Или прочитайте, что между 2-м и 3-м / как Text2 затем прочитайте, что после : что такое Text4 и сделайте ;Text4 .

Таким образом, в конечном результате файл Result.txt будет иметь

Text2;Text4

В любом случае будет работать, лучше тот, который работает быстрее.

PS: Тексты могут иметь пробелы, символы и точки внутри, но оригинальные разделители из текстов всегда / / / которые не появляются нигде в текстах.

Это должно быть сделано во всех строках File.txt .


файлы:

File1.txt

/Soccer.Teacher/Michael.John/Group1:monday-friday - 14h to 16h
/Basketball.Teacher/Susana.Stevens/Group2:tuesday-thursday-3pm-to-5pm
/Tennis.Teacher/Josh.Karen/Group3:monday-wednesday-5pm_to_7pm

и т.п.

Result.txt быть:

Michael.John:monday-friday - 14:00 to 16:00
Susana.Stevens:tuesday-thursday-3pm-to-5pm
Josh.Karen:monday-wednesday-5pm_to_7pm

и т.п.

3 ответа3

2

sed делает это:

echo '/Text1/Text2/Text3:Text4' | sed -E 's/\/([a-zA-Z0-9]+)\/([a-zA-Z0-9]+)\/([a-zA-Z0-9]+):([a-zA-Z0-9]+)/\2;\4/'
  • -E использовать расширенные регулярные выражения
  • \/ использовать escape-символ для spesific / char
  • ([a-zA-Z0-9]+) определить, скажем, слово шаблон области.
  • \2;\4 доступ ко второй и четвертой частям региона.

в соответствии с вашим последним изданием:

sed -E 's/\/([^/]+)\/([^/]+)\/([^/:]+):([^/]+)$/\2;\4/' FileName
1

Не самое короткое / быстрое решение, но оно выполнено и легко для понимания:

#!/bin/bash

while read -r line; do
    echo -n "$line" | cut -d "/" -f 3 | tr -d $'\n'
    echo -n ";"
    echo "$line" | cut -d ":" -f 2
done < "File1.txt"

-n для первых двух echo сигналов важно, поэтому все в одной строке.

Поскольку ваша версия cut не поддерживает -z the | tr -d $'\n' необходим, чтобы удалить завершающий перевод строки.

1

Тексты могут иметь пробелы, символы и точки внутри, но оригинальные разделители из текстов всегда / / / которые не появляются нигде в текстах.

Не правда. Вы привели пример с 14:00 to 16:00 . На мгновение предположим, что это правда. Это позволяет простой подход:

tr ':' '/' | cut -d '/' --output-delimiter=';' -f 3,5

tr объединяет разделители, а затем cut выбирает нужные поля.

Заметки:

  • --output-delimiter не требуется для POSIX. Если ваш cut не поддерживает это, это альтернатива:

    tr ':' '/' | cut -d '/' -f 3,5 | tr '/' ';'
    

    Обратите внимание, мы не можем использовать tr ':' ';' как первая команда в конвейере (которая упростила бы все остальное), потому что вы не гарантируете этого ; не появляется во входных данных (cut будет сбит с толку, если это произойдет).

  • cut принимает поля 3 и 5 (не 2 и 4), потому что все, что находится перед первым разделителем, уже является полем 1 (пустая строка в вашем случае).

Однако, если только первый : должен быть разделителем, тогда команда может быть:

sed 's|:|/|' | cut -d '/' --output-delimiter=';' -f 3,5

sed 's|:|/|' заменит только первое вхождение : (в отличие от sed 's|:|/|g' что эквивалентно нашему оригинальному tr ':' '/').


Если вы не знакомы со стандартным способом использования таких фильтров с файлами, это правильный синтаксис (с sed и POSIX-совместимым cut):

< File1.txt sed 's|:|/|' | cut -d '/' -f 3,5 | tr '/' ';' > Result.txt

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .