заменить подстроку последним специальным символом, будучи (3-я часть) строки, разделенной запятой - PullRequest
1 голос
/ 29 октября 2019

У меня есть строка со значениями, разделенными запятыми, например:

742108,SOME-STRING_A_-BLAHBLAH_1-4MP0RTTYE,SOME-STRING_A_-BLAHBLAH_1-4MP0-,,,

Как видите, третье значение, разделенное запятыми, иногда имеет специальный символ, такой как тире (-), в конце. Я хочу использовать sed или, предпочтительно, команду perl, чтобы заменить эту строку (с параметром -i, чтобы заменить существующий файл), на ту же строку в том же месте (т. Е. 3-е значение, разделенное запятыми), но без специального символа (как тире (-)) в конце строки. Итак, результат в приведенном выше примере строки должен быть:

742108,SOME-STRING_A_-BLAHBLAH_1-4MP0RTTYE,SOME-STRING_A_-BLAHBLAH_1-4MP0,,,

Поскольку такие несколько строк, как указано выше, находятся внутри файла, я использую цикл while в сценарии shell / bash, чтобы выполнить цикл и манипулировать всеми строками файла. ,И я назначил вышеуказанные строковые значения переменным, чтобы заменить их с помощью perl. Итак, мой цикл while:

while read mystr
do
myNEWstr=$(echo $mystr | sed s/[_.-]$// | sed s/[__]$// | sed s/[_.-]$//)
perl -pi -e "s/\b$mystr\b/$myNEWstr/g" myFinalFile.txt
done < myInputFile.txt

, где:

$mystr is the "SOME-STRING_A_-BLAHBLAH_1-4MP0-"
$myNEWstr result is the "SOME-STRING_A_-BLAHBLAH_1-4MP0"

Обратите внимание, что myInputFile.txt - это файл, который содержит 3-е разделенные запятыми значения myFinalFile.txt, поэтомучто эти строковые значения EXACT ($ mystr) будут проверены на наличие специальных символов в конце, таких как подчеркивание, тире, точка, двойное подчеркивание, и если они существуют, чтобы удалить их и сформировать новую строку ($ myNEWstr), то, наконец,новая строка ($ myNEWstr), которая должна быть заменена в myFinalFile.txt, чтобы иметь результирующие строки, такие как пример финальной строки, показанной выше, то есть со значением подстроки, разделенной запятой 3-й, БЕЗ специального символа в конце (который являетсятире (-) в приведенном выше примере).

Спасибо.

1 Ответ

2 голосов
/ 29 октября 2019

Вы можете использовать следующее регулярное выражение:

s/^([^,]*,[^,]*,[^,]*)-,/$1,/

Это поля csv определены как серии символов, отличных от запятой (допускаются пустые поля). Мы ищем тире в самом конце третьего поля CSV. Регулярное выражение захватывает все до тех пор, пока не будет там, а затем заменяет его, не используя тире.

$ cat t.txt
742108,SOME-STRING_A_-BLAHBLAH_1-4MP0RTTYE,SOME-STRING_A_-BLAHBLAH_1-4MP0-,,,
]$ perl -p -e 's/^([^,]*,[^,]*,[^,]*)-,/$1,/' t.txt
742108,SOME-STRING_A_-BLAHBLAH_1-4MP0RTTYE,SOME-STRING_A_-BLAHBLAH_1-4MP0,,,
]$
...