wyświetl i usuń wszystkie znaki> kod ASCII 127

2

Jak mogę wyświetlić i usunąć wszystkie znaki> kod ascii 127 z pliku?

plik ma format 16bit

AKTUALIZACJA Dennis rozwiązał go, ale istnieje interesująca dyskusja na temat zakresów liczb.

barlop
źródło
Dlaczego tego potrzebujesz?
grawity
@gravvity dlaczego pytasz?
barlop
Ponieważ ma to wpływ na to, jak sobie z tym poradzisz. Dodatkowe pytanie: czy masz narzędzia w stylu uniksowym dostępne przez Cygwin, GNUWin32 lub podobny?
Dennis Williamson
@Dennis Williamson Jestem otwarty na wiele opcji. Mam zarówno Cygwin, jak i Gnuwin32, byłoby miło to zrobić za ich pośrednictwem, ale problemem jest to, że mój plik ma format 16bit. Zauważam, że linia: cat | od -c interpretuje \ 0s między każdym char, a grep na nim nie działa, ponieważ litery abc widziane przez grep nie są ciągłe z przypuszczalnie tego samego powodu. zakładają 8 bitów na znak.
barlop
Ponieważ masz plik Unicode, powinieneś wiedzieć, że to jest prawdziwy powód grawitacji i poprosiłem o dodatkowe informacje. Usunięcie bajtów z wartościami bajtów (zauważ, że nie powiedziałem „znaków” i „kodów ASCII”) z pliku Unicode da dziwne wyniki. Co tak naprawdę próbujesz zrobić?
Dennis Williamson

Odpowiedzi:

1

Jednym z podejść byłoby przekonwertowanie pliku na cyfry szesnastkowe, usunięcie niepotrzebnych wzorów cyfr, a następnie konwersja z powrotem.

$ echo 'A Unicode character: [ñ]' | xxd -p | sed 's/c3b1//' | xxd -r -p
A Unicode character: []

Zamiast niego możesz użyć AWK lub innej techniki manipulacji tekstem sed. Uważaj na niejednoznaczne sekwencje.

Daj mi znać, jeśli podejdzie to do tego, co masz na myśli.

Dennis Williamson
źródło
tak, to zbliża się do tego, co mam na myśli
barlop
stamtąd widzę, jak bym to zrobił .. od -x mój_plik | przeciąć, aby ominąć FEFF na początku, uchwycić pary w wyrażeniu regularnym w moim zasięgu heksowym, w sed.
barlop
tak naprawdę mój pomysł na cięcie nie dałby mi rady… ale tak, pomysł programu lub zestawu, który mógłby pozwolić mi zobaczyć hex, pracować z regexem na hexie i napisać go z powrotem, to jedno ogólne podejście, o którym myślałem… Byłbym zainteresowany, aby zobaczyć, jak dostosujesz go do wymagań. Zachęcamy do publikowania innych szkiców podejść, jeśli coś przychodzi ci na myśl ... jeśli nie jest to zbyt duży problem. byłbym zainteresowany i myślę, że przydałoby się.
barlop
docieram do tego szkicu, który dałeś, i używając cięcia, przegapiłem tr -d '\ n' przed nim ..
barlop 31.01.11
tak naprawdę utknąłem próbując ulepszyć swój szkic. twój szkic jest w porządku (oczywiście, jak wiesz!), ale problem polega na mojej modyfikacji. bo wiem, że po | tr -d '\ n', a następnie wytnij 5-, co działa, nie chcę po prostu skanować w poszukiwaniu FEFF lub [8-F] [0-F] [0-F] [0-F], ponieważ nie chcę nakładać się na bajty z 2 znaków. I cokolwiek umieszczę w sekcji znajdowania seds idzie. Więc jeśli spróbuję dopasować każdą parę bajtów, to spowoduje to usunięcie partii. i nie jestem pewien, jak i czy możliwe jest warunkowe zastąpienie par bajtów przez sed.
barlop
0

Patrząc wstecz na to pytanie

Wygląda na to, że ostatecznie użyłem jednej z tych linii

(wydaje się być wyrażeniem regularnym Dennisa)

$ xxd -p a.q | tr -d '\n' | sed "s/([0-9a-f]\{4\})/\1 /g" | sed -r "s/(00[8-9a-f][0-9a-f]|[0-9a-f][1-9a-f][0-9a-f][0-9a-f]|[1-9a-f]0[0-9a-f][0-9a-f])//g" | tr -d ' ' | sed "s/(.*)/feff\1/" | xxd -r -p >a.q2

lub to (wydaje się być moim wyrażeniem regularnym)

$ xxd -p a.q | tr -d '\n' | sed "s/([0-9a-f]\{4\})/\1 /g" | sed -r "s/(00[89A-F][0-9A-F]|0[1-9A-F][0-9A-F]{2}|[1-9A-F][0-9A-F]{3})//g" | tr -d ' ' | sed "s/(.*)/feff\1/" | xxd -r -p >a.q2

to jest komentarz na temat tego, jak to wypracowałem, z kilkoma testami.

0080-00FF     00[89A-F][0-9A-F]
0100-0FFF     0[1-9A-F][0-9A-F]{2}
1000-FFFF     [1-9A-F][0-9A-F]{3}

a oto kilka testów, które pokazują, że regex działa. Zadałem je, gdy je rozwiązałem, ale powinienem był udzielić odpowiedzi.

Łączne znaki szesnastkowe 85

$ xxd -u -p a.aa.txt | sed -r "s/.{4}/\0 /g" | grep -oE "[0-9A-F]{4}" | wc -l
85

Ogółem, czego chcę, 72

$ xxd -u -p a.aa.txt | sed -r "s/.{4}/\0 /g" | grep -oE "00[0-7][0-F]" | wc -
l
72

Suma, której nie chcę, 13

$ xxd -p -u a.aa.txt | sed -r "s/[0-9A-F]{4}/\0 /g" | grep -oP '((?!00[0-7][0-9A-F])(?=[^ ]).){4}' | wc -l
13

Suma, której nie chcę, 13

$ xxd -u -p a.aa.txt | sed -r "s/.{4}/\0 /g" | grep -oE "00[89A-F][0-9A-F]|0[1-9A-F][0-9A-F]{2}|[1-9A-F][0-9A-F]{3}" | wc –l
13
barlop
źródło
i patrząc na to teraz zastanawiam się, dlaczego nie wymazałem po prostu znaków szesnastkowych z Unicode, które chciałem zachować, jak w tym teście, $ xxd -u -p a.aa.txt | sed -r "s/.{4}/\0 /g" | grep -oE "00[0-7][0-F]" zamiast zastąpić te, których nie chciałem zachować z niczym. (to ostatnie oznacza znacznie dłuższy regex)
barlop
tak przy okazji, pierwsza linia xxd -p aq używa wyrażenia regularnego w komentarzu dennisa, druga używa wyrażenia regularnego, które wymyśliłem.
barlop