2011-12-20 27 views
10

Chip, Dirkland, DrobæSphere Inc, cdirkland @ hotmail.com, usaSkip/gỡ bỏ các nhân vật phi ascii với sed

Tôi đã cố gắng sử dụng sed để thay đổi địa chỉ email trong một .csv nhưng dòng trên tiếp tục vấp ngã tôi lên, sử dụng lệnh như:

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

from this stackoverflow question

dường như không làm việc như tôi nhận được một lỗi 'nhân vật đối chiếu không hợp lệ'.

Lý tưởng nhất là tôi không muốn thay đổi ký tự kết hợp AE đó, tôi thích sed chỉ cần bỏ qua ngay khi tôi không cố gắng thao tác văn bản đó mà đúng hơn là địa chỉ email. Miễn là đó là AE trong đó mặc dù nó gây ra sự thay thế sed của tôi thất bại sau một dòng, xóa các ký tự và nó xử lý toàn bộ tập tin tốt.

Bất kỳ ý tưởng nào?

Trả lời

4

Điều này có thể làm việc cho bạn (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 

Sau đó, làm những gì bạn phải làm và sau để trở lại làm:

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

Nếu bạn có nhân vật phức tạp trong chuỗi và muốn để hiểu cách sed thấy chúng sử dụng lệnh l0 (xem here). Cũng rất hữu ích cho việc gỡ lỗi các regexp khó.

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

+1 cho 'l0'. Có một kịch bản 'sedsed.py' khác, có sẵn [ở đây] (http://aurelio.net/sedsed/). Hữu ích khi kiểm tra các vùng 'mẫu' và' giữ'. Có thể không giúp đỡ trong trường hợp này nhưng một công cụ gỡ lỗi hữu ích không kém. :) –

+0

lệnh sed -n 'l0' thú vị, những gì nó in ra cho công ty là: Drob \ 357 \ 277 \ 275Sphere Inc – xref

+0

và tôi vẫn không thể lấy các ví dụ trên để làm việc với nó, có lẽ là ký tự (trong đó cho thấy là một AE trong Windows LibreOffice nhưng không nơi nào khác) thực sự là một nhân vật đặc biệt nói rằng nó không thể được đại diện trong unicode? http://www.fileformat.info/info/unicode/char/fffd/index.htm – xref

0

Cách sử dụng awk cho việc này. Chúng tôi thiết lập Phân tách trường thành không có gì. Sau đó lặp lại từng ký tự. Sử dụng số if loop để kiểm tra xem nó có khớp với số character class của chúng tôi hay không. Nếu chúng tôi in nó, chúng tôi sẽ bỏ qua nó.

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

Test:

[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 

Cập nhật:

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

Tôi đã thêm printf "\ n" sau khi vòng lặp để giữ cho dòng riêng biệt.

+0

Cảm ơn Jaypal, làm thế nào điều này sẽ được sửa đổi nếu bạn muốn xử lý datafile.csv và xuất ra asciidata.csv? – xref

+0

Tôi đã cập nhật câu trả lời. Hy vọng rằng sẽ giúp! –

+0

Nếu bạn chỉ muốn địa chỉ e-mail được trích xuất từ ​​tập tin đầu vào của bạn thì 'awk' có thể làm điều đó một cách dễ dàng mà không cần bất kỳ' regex' phức tạp nào. Hãy cho tôi biết phải làm như thế nào. –

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

Ngoài ra, đây hoạt động như dos2unix

+0

Không hoạt động. [: print:] không giống ASCII, ví dụ: 'ü' có thể in được nhưng không thể in được ASCII. –

1

Tôi đến đây để thử lệnh sed này s/[\x00-\x1F]/ /g;, đã cho tôi thông báo lỗi tương tự.

trong trường hợp này nó chỉ đơn giản cũng đủ để loại bỏ các \x00 từ collation, năng suất s/[\x01-\x1F]/ /g;

Đáng tiếc là dường như tất cả các nhân vật trên và bao gồm \x7F và một số người khác là không được phép, như có thể thấy với kịch bản ngắn này:

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 

Lưu ý rằng sự cố chỉ là việc sử dụng các ký tự đó để chỉ định dải ô. Bạn vẫn có thể liệt kê tất cả chúng theo cách thủ công hoặc cho mỗi tập lệnh. Ví dụ. trở lại với ví dụ của bạn:

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

sẽ trở thành

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

đó sẽ dịch để:

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

"_Rất tiếc dường như tất cả các ký tự ở trên và bao gồm \ x7F và một số ký tự khác không được phép_". Cảm ơn! Điều đó giải thích tại sao tôi nhận được lỗi 'Ký tự đối chiếu không hợp lệ'. – xpt

Các vấn đề liên quan