2011-12-20 16 views
10

Chip, Dirkland, DrobæSphere Inc, cdirkland @ hotmail.com, usaSkip/usuń znak spoza ASCII z sed

Próbowałem użyć sed zmodyfikować adresy e-mail w formacie .csv ale linia powyżej trzyma potknięcia mnie, za pomocą poleceń takich jak:

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

from this stackoverflow question

nie wydają się działać jak pojawia się błąd „nieprawidłowy znak zestawień”.

Idealnie nie chcę w ogóle zmieniać tej połączonej postaci AE, wolałbym ją raczej pominąć, ponieważ nie próbuję manipulować tym tekstem, ale raczej adresami e-mail. Dopóki ta AE jest w tym samym miejscu, ale powoduje, że moja substytucja sed ulegnie awarii po jednej linii, usuń znak i przetwarza cały plik w porządku.

Wszelkie pomysły?

Odpowiedz

4

To może pracować dla Ciebie (GNU sed):

echo "Chip,Dirkland,DrobæSphere Inc,[email protected],usa" | 
sed 's/\o346/a+e/g' 
Chip,Dirkland,Droba+eSphere Inc,[email protected],usa 

Wtedy to, co trzeba zrobić, a potem powrócić zrobić:

echo "Chip,Dirkland,Droba+eSphere Inc,[email protected],usa" | 
sed 's/a+e/\o346/g' 
Chip,Dirkland,DrobæSphere Inc,[email protected],usa 

Jeśli masz postacie skomplikowane w ciągach znaków i chcą aby zrozumieć, w jaki sposób sed widzi, że używają polecenia l0 (patrz here). Również bardzo przydatne do debugowania trudnych regexps.

echo "Chip,Dirkland,DrobæSphere Inc,[email protected],usa" | 
sed -n 'l0' 
Chip,Dirkland,Drob\346Sphere Inc,[email protected],usa$ 
+0

+1 dla "l0". Istnieje również inny skrypt 'sedsed.py', dostępny [tutaj] (http://aurelio.net/sedsed/). Przydatne do sprawdzenia przestrzeni 'pattern' i' hold'. W tym przypadku może to nie pomóc, ale przydatne narzędzie do debugowania. :) –

+0

Polecenie sed -n 'l0' jest interesujące, to, co drukuje dla firmy to: Drob \ 357 \ 277 \ 275Sphere Inc – xref

+0

i nadal nie mogę uzyskać powyższych przykładów do pracy z nim, być może postać (który pokazuje się jako AE w Windows LibreOffice, ale nigdzie indziej) jest w rzeczywistości specjalnym znakiem mówiącym, że nie może być reprezentowany w Unicode? http://www.fileformat.info/info/unicode/char/fffd/index.htm – xref

0

Co do korzystania z tego celu przy użyciu awk. Ustawiamy Separator pola na zero. Następnie zapętlić każdy znak. Użyj if loop, aby sprawdzić, czy pasuje do naszego character class. Jeśli to zrobimy, drukujemy to inaczej, ignorujemy to.

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

testu:

[jaypal:~/Temp] echo "Chip,Dirkland,DrobæSphere Inc,[email protected],usa" | 
awk -v FS="" '{for(i=1;i<=NF;i++) if($i ~ /[A-Za-z,[email protected] ]/) printf $i}' 
Chip,Dirkland,DrobSphere Inc,[email protected],usa 

Update:

awk -v FS="" '{for(i=1;i<=NF;i++) if($i ~ /[A-Za-z,[email protected] ]/) printf $i; printf "\n"}' <datafile.csv> asciidata.csv 

I dodano printf "\ n", po pętli utrzymania linii rozdzielenia.

+0

Dzięki Jaypal, w jaki sposób miałoby to być modyfikowane, jeśli chce przetwarzać datafile.csv i wyjściowy asciidata.csv? – xref

+0

Zaktualizowałem odpowiedź. Mam nadzieję, że pomaga! –

+0

Jeśli chcesz tylko adres e-mail wyodrębniony z pliku wejściowego, 'awk' może to zrobić na wietrze bez złożonego' regex'. Daj mi znać, jak to działa. –

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

Również ten działa jak dos2unix

+0

Nie działa. [: print:] to nie to samo co ASCII, np. 'ü' można wydrukować, ale nie ASCII. –

1

Przyszedłem tu próbując tego polecenia sed s/[\x00-\x1F]/ /g;, które dało mi ten sam komunikat o błędzie.

w tym przypadku po prostu wystarczy zdjąć \x00 z zestawień, otrzymując s/[\x01-\x1F]/ /g;

Niestety wydaje się, że wszystkie znaki powyżej i tym \x7F i inni są niedozwolone, jak widać z tego krótkiego skryptu:

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 

Należy pamiętać, że problem polega jedynie na wykorzystaniu tych znaków do określenia zakresu. Wciąż możesz wyświetlić je wszystkie ręcznie lub według skryptu. Na przykład. wrócić do swojej przykład:

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

staną

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

co przekłada się na:

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 
+0

"_Niestety wydaje się, że wszystkie powyższe znaki, w tym \ x7F, a inne są niedozwolone". Dzięki! To wyjaśniało, dlaczego otrzymuję komunikat o błędzie "Nieprawidłowy znak sortowania". – xpt

Powiązane problemy