Удалить неизвестные специальные символы из файла - PullRequest
1 голос
/ 11 ноября 2019

Я хочу удалить все специальные символы, кроме |, _, - и .s, из файла, разделенного каналом.

Например, мой файл данных выглядит так:

tr -cd '[:print:]' < temp.txt > newfile -- I still get all the special chars.
tr -cd '[:alnum:]' <temp.txt -- I get only aphanum chars but I want to have a few special chars.
cat temp.txt | sed 's/[a-zA-Z0-9|_-.]//g' | sed '/^$/d' -- I get all the special chars but repetition is there

Ниже приведены выходные данные в виде

$ cat temp.txt | sed 's/[a-zA-Z0-9|_-.]//g' | sed '/^$/d' | tr -cd '[:print:]' | sort -u
""""){***+#=**~>>\+*****<(")

Если я хотя бы получу все уникальные специальные символы, я смогу поместить все в sed и заменить назначение NULL.

Мой ожидаемый результат:

ABCD|123|Name
EFGH|456|New-Name
IJKL|789|New_Name
MNOP|123|New_name
QRST|124|New_name
UVWX|353|Name_NAME
EFGH|456|New_Name
Eaba|456|New_Name
fdsf|456|New_Name
iouk|456|New_Name

Мне нужно посмотреть на конкретный столбец, если это поможет в сокращении кода. Как было сказано ранее, код должен включать символы |, _, - и удалять все остальное. Дайте мне знать, если вы, ребята, ищете больше информации.

Ответы [ 5 ]

3 голосов
/ 11 ноября 2019

Надеюсь, я правильно выполнил ваши требования:

  1. Заменить группы из нескольких - (например, ---) на _.
    (если это опечатка вв вашем примере просто удалите строку sed в этом ответе.)
  2. Замените все символы, кроме букв, цифр, | и - на _.
  3. Сжатие повторяется - и _ (например, ----).
  4. Удалите начальные подчеркивания в каждом | -разделенном поле.

TheСледующий скрипт реализует эти требования в том же порядке (первая строка для первого требования и т. д.). Обратите внимание, что tr не основан на строках и интерпретирует символы новой строки как любой другой символ, поэтому мы должны явно указать tr, чтобы сохранить символ новой строки \n. Также обратите внимание, что - необходимо экранировать в аргументах tr.

f() {
     sed 's/---*/_/g' |
     tr -c  '[:alnum:]|\-\n' _ |
     tr -s  '\-_' |
     sed -E 's/(^|\|)_/\1/g'
}

Используйте эту функцию как

f  <infile  >outfile
2 голосов
/ 11 ноября 2019

Звучит как «специальный символ», который вы имеете в виду не буквенно-цифровой. Если это так, то просто используйте отрицание класса символов [:alnum:], чтобы сопоставить эти символы, например, с любым awk в любой оболочке на каждом блоке UNIX и только изменяя столбец 3, поскольку вы сказали «Мне нужно посмотреть на конкретный столбец»:

$ awk 'BEGIN{FS=OFS="|"} {gsub(/[^[:alnum:]-]+|--+/,"_",$3)} 1' file
ABCD|123|Name
EFGH|456|New-Name
IJKL|789|New_Name
MNOP|123|New_name
QRST|124|New_name
UVWX|353|Name_NAME
EFGH|456|New_Name
Eaba|456|New_Name
fdsf|456|New_Name
iouk|456|New_Name

Если [^[:alnum:]-] не так, просто используйте любой класс символов, который вы хотите, и / или перечислите конкретные символы [^*\/%-]. Обратите внимание, что вам не нужно явно обрабатывать | в регулярных выражениях, поскольку не может быть | в | -разделенном поле.

1 голос
/ 11 ноября 2019

Почему не просто так:

sed -E 's/[*/_%=#()^$]+|-+/_/g' file
ABCD|123|Name
EFGH|456|New_Name
IJKL|789|New_Name
MNOP|123|New_name
QRST|124|New_name
UVWX|353|Name_NAME
EFGH|456|New_Name
Eaba|456|New_Name
fdsf|456|New_Name
iouk|456|New_Name
0 голосов
/ 11 ноября 2019
  awk 'NR>2{sub(/New./,"New_")sub(/_..NAME/,"_NAME")sub(/_.*Name/,"_Name")}1' file
ABCD|123|Name
EFGH|456|New-Name
IJKL|789|New_Name
MNOP|123|New_name
QRST|124|New_name
UVWX|353|Name_NAME
EFGH|456|New_Name
Eaba|456|New_Name
fdsf|456|New_Name
iouk|456|New_Name
Eaba|456|New_Name
fdsf|456|New_Name
iouk|456|New_Name
0 голосов
/ 11 ноября 2019

Это может работать для вас (GNU sed):

sed -E 's/[^[:alnum:]|_.,*=/-]//g;s/[*=/]+/_/g;s/--+|__+/_/g' file

Первая замена удаляет все нежелательные символы.

Вторая замена заменяет еще один *, = или/ с одним _ по всему файлу.

Третья замена заменяет два или более - или _ на один _ по всему файлу.

NBМетасимвол чередования | и разделитель подстановки / могут представлять свои действительные значения внутри выражения в скобках, поэтому sed -E 's/[/|]//g' file удалит все вхождения / и |. Кроме того, - в выражении в скобках может представлять диапазон, [a-zA-Z0-9] означает любой отдельный буквенно-цифровой символ, эквивалентный [[:alnum:]], но если он помещен непосредственно перед закрывающей скобкой, он представляет его реальное значение, поэтому sed 's/[a-]//g' fileудалит все вхождения a и -.

Окончательная замена может быть изменена на s/(-)-+|(_)_+/\1\2/g, что эквивалентно s/--+/-/g;s/__+/_/g, если пользователь желает сократить эти посторонние символы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...