Mam nazwy użytkownika pliku i hasła w formacie JSON, które chcę przekonwertować do przetworzenia.
Użyłem sed
w różnych poleceń, aby go przetworzyć, ale to, co chciałbym wiedzieć, jak lump wszystkie trzy polecenia do jednego na przyszłość.
Oryginalny format
{ "user.name1" : "hashed_password",
"user.name2" : "hashed_password" }
Pożądane wyjście
user.name:hashed_password
Są to komendy wpadłem, jednak nie udało mi się je ze sobą za pomocą łańcucha albo rur lub po prostu łącząc je tam, gdzie pojawia się błąd, sed: -e expression #1, char 8: unknown option to 's'
.
Obraźliwe polecenie ...
sed -i 's/\"//g/s/\,/\n/g/\s//g' input_file
sed: -e expression #1, char 8: unknown option to `s'
Jak można połączyć poniższe polecenia w jedno?
Polecenia Usuń podwójne cudzysłowy
sed -i 's/\"//g' input_file
Zastąp przecinek nową linią
sed -i 's/\,/\n/g' input_file
Usuń białe znaki
sed -i 's/\s//g input_file
sed -i '' -e …
aby zrobić to poprawnie na BSD. W przeciwnym razie zostanie zapisany plik kopii zapasowej o nazwieinput_file-e
Kiedy masz do czynienia ze standardowymi danymi wejściowymi, takimi jak JSON, ogólnie lepiej jest użyć odpowiedniego parsera niż wyrażenia regularnego. Na przykład poprawnie skonwertujesz sekwencje specjalne (choć może to nie być możliwe w przypadku danych wejściowych!).
Niestety nie ma świetnych narzędzi do radzenia sobie z JSON w coreutils. Attie jest dostępna
jq
jako przyzwoita opcja, jeśli możesz swobodnie instalować pakiety.Jeśli nie możesz zainstalować dodatkowych pakietów, nie jest to szczególnie trudne w Pythonie. Weźmy na przykład ten skrypt:
Które można skompresować do jednej linii:
źródło
Dla prostego usuwania znaków, które wykonujesz za pomocą tych
sed
poleceń, poleciłbym zamiast tego użyćtr
, którego jedynym celem jest usuwanie, wyciskanie lub zastępowanie pojedynczych znaków, w tym znaków nowej linii (sed
jest oparty na wyrażeniach regularnych, które zwykle polegają na znakach nowej linii jako separatorach buforowych, więc używanie sed do modyfikowania nowych linii jest trudne). Myślę, że totr
polecenie robi wszystko, czego szukasz:Pierwsze
tr
polecenie usuwa wszystkie nawiasy klamrowe, podwójne cudzysłowy, spacje, znaki powrotu karetki (ósemkowe 012, ascii 10), tabulatory (ósemkowe 011, ascii 9 i linefeed (ósemkowe 015, ascii 13). Drugietr
polecenie zastępuje wszystkie przecinki zwraca karetkę. Tak długo, jak nazwy zmiennych i wartości pliku JSON nie zawierają przecinków, polecenia te pozwoliłyby uniknąć potrzeby dedykowanego analizatora składni JSON.To powiedziawszy, jeśli masz zestaw
sed
poleceń, z których każde działa niezależnie, ich połączenie można najłatwiej wykonać za pomocą opcji „-f”sed
do odczytania osobnych poleceń z pliku. Wystarczy umieścić ciągi s /.../.../ g w pliku, każdy ciąg w osobnym wierszu, a następnie podać nazwę pliku po opcji „-f”. Na przykład, jeśli trzysed
wymienione polecenia są zadowalające, możesz umieścić je w pliku o nazwie „json.convert.sed”, który po prostu zawiera:Następnie wywołałbyś
sed
ten plik poleceń za pomocą:To powiedziawszy, te
sed
polecenia nie działają dla mnie, aby osiągnąć to, czego chcesz, i nie jestem pewien, czy kiedykolwiek możeszsed
zmodyfikować znaki nowego wiersza. Wynika to z faktu, żesed
oparty jest na starym edytorze linii „ed”, przeznaczonym do edycji pojedynczych linii naraz (jego wersja obsługiwana przez „skrypt”), więc każdy wiersz danych wejściowych jest „analizowany” przy użyciu znaku nowej linii jako separatora, a następnie linia (bez nowej linii) jest przekazywana do silnika edycji, stosowane są polecenia edycji, a następnie edytowana linia jest wypisywana z nową linią. Następnie pętla się powtarza. Byłem w stanie tylko użyćsed
do modyfikacji nowej linii, najpierw zmieniając nową linię na jakiś odrębny znak (który inaczej nie pojawia się na wejściu) przy użyciutr
. Tam'tr
tr
zrobi to za ciebie. Ale jeśli na przykład chcesz przekonwertować znaki nowej linii na średniki ze spacją końcową, jednym ze sposobów jest:( znaki nowej linii są konwertowane na% przez
tr
, a następniesed
konwertują wszystkie% znaków na pary znaków „;”).źródło
Sed radzi sobie z edytowaniem wielu wierszy, ale zgadzam się z Attie i Bobem, parsowanie Jsona z wyrażeniem regularnym może stać się koszmarem.
źródło
Możesz to połączyć w następujący sposób:
sed -i 's/\"//g;s/\,/\n/g;s/\s//g' input_file
Zapomniałeś dodać usunięcie
{}
. Więc prawdopodobnie chcesz:sed -i 's/\"//g;s/\,/\n/g;s/\s//g;s/{//g;s/}//g' input_file
źródło