Пропустить / удалить символ без ascii с помощью sed

Chip, Dirkland, DrobæSphere Inc,cdirkland@hotmail.com, США

Я пытался использовать sed для изменения адресов электронной почты в a .csv, но строка выше продолжает меня запутывать, используя такие команды, как:

sed -i 's/[d128-d255]//' FILENAME

из этого вопроса stackoverflow

не работает, поскольку я получаю ошибку "недопустимый символ сортировки".

В идеале я не хочу менять этот комбинированный символ AE вообще, я бы предпочел просто пропустите прямо над ним, поскольку я не пытаюсь манипулировать этим текстом, а скорее адресами электронной почты. Пока этот AE находится там, хотя это приводит к сбою моей замены sed после одной строки, удалите символ, и он обрабатывает весь файл нормально.

какие идеи?

5 ответов


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

echo "Chip,Dirkland,DrobæSphere Inc,cdirkland@hotmail.com,usa" |
sed 's/\o346/a+e/g'
Chip,Dirkland,Droba+eSphere Inc,cdirkland@hotmail.com,usa

затем сделайте то, что вам нужно сделать, и после возврата сделайте:

echo "Chip,Dirkland,Droba+eSphere Inc,cdirkland@hotmail.com,usa" | 
sed 's/a+e/\o346/g'
Chip,Dirkland,DrobæSphere Inc,cdirkland@hotmail.com,usa

если у вас есть сложные символы в строках и вы хотите понять, как sed видит, что они используют (см. здесь). Также очень полезно для отладки сложных регулярных выражений.

echo "Chip,Dirkland,DrobæSphere Inc,cdirkland@hotmail.com,usa" | 
sed -n 'l0'
Chip,Dirkland,Drob6Sphere Inc,cdirkland@hotmail.com,usa$

sed -i 's/[^[:print:]]//' FILENAME

кроме того, это действует как dos2unix


Я пришел сюда, эту команду sed s/[\x00-\x1F]/ /g;, которая дала мне то же сообщение об ошибке.

в этом случае достаточно просто удалить \x00 от сортировки, поддавшись s/[\x01-\x1F]/ /g;

к сожалению, кажется, что все символы выше и в том числе \x7F и некоторые другие запрещены, как видно из этого короткого сценария:

for (( i=0; i<=255; i++ )); do 
    printf "== $i - \x$(echo "ibase=10;obase=16;$i" | bc) =="
    echo '' | sed -E "s/[\d$i-\d$((i+1))]]//g"
done

обратите внимание, что проблема заключается только в использовании этих символов для указания диапазона. Вы все еще можете перечислить их все вручную или по сценарию. Е. Г. вернуться к вашему примеру:

sed -i 's/[\d128-\d255]//' FILENAME

станет

c=; for (( i=128; i<255; i++ )); do c="$c\d$i"; done
sed -i 's/['"$c"']//' FILENAME

что бы перевести на:

sed -i 's/[\d128\d129\d130\d131\d132\d133\d134\d135\d136\d137\d138\d139\d140\d141\d142\d143\d144\d145\d146\d147\d148\d149\d150\d151\d152\d153\d154\d155\d156\d157\d158\d159\d160\d161\d162\d163\d164\d165\d166\d167\d168\d169\d170\d171\d172\d173\d174\d175\d176\d177\d178\d179\d180\d181\d182\d183\d184\d185\d186\d187\d188\d189\d190\d191\d192\d193\d194\d195\d196\d197\d198\d199\d200\d201\d202\d203\d204\d205\d206\d207\d208\d209\d210\d211\d212\d213\d214\d215\d216\d217\d218\d219\d220\d221\d222\d223\d224\d225\d226\d227\d228\d229\d230\d231\d232\d233\d234\d235\d236\d237\d238\d239\d240\d241\d242\d243\d244\d245\d246\d247\d248\d249\d250\d251\d252\d253\d254\d255]//' FILENAME

как насчет использования awk для этого. Мы настраиваем разделитель полей на nothing. Затем цикл над каждым символом. Используйте if loop чтобы проверить, соответствует ли он нашему character class. Если же мы печатаем еще мы его игнорируем.

awk -v FS="" '{for(i=1;i<=NF;i++) if($i ~ /[A-Za-z,.@ ]/) printf $i}'


в этом случае есть способ просто пропустить символы, отличные от ASCII, не беспокоясь об удалении.

LANG=C sed /someemailpattern/

см.https://bugzilla.redhat.com/show_bug.cgi?id=440419 и будет ли sed (и другие) повреждать файлы, отличные от ASCII?.