Пропустить / удалить символ без 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 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?.