Mam bardzo duży plik csv. Jak ,
usunąłbyś ostatni przy pomocy sed (lub podobnego)?
...
[11911,0,"BUILDER","2014-10-15","BUILDER",0,0],
[11912,0,"BUILDER","2014-10-15","BUILDER",0,0],
[11913,0,"BUILDER","2014-10-15","BUILDER",0,0],
]
Pożądane wyjście
...
[11911,0,"BUILDER","2014-10-15","BUILDER",0,0],
[11912,0,"BUILDER","2014-10-15","BUILDER",0,0],
[11913,0,"BUILDER","2014-10-15","BUILDER",0,0]
]
Następujące polecenie sed usunie ostatnie wystąpienie w wierszu, ale chcę na plik.
sed -e 's/,$//' foo.csv
To też nie działa
sed '$s/,//' foo.csv
Odpowiedzi:
Za pomocą
awk
Jeśli przecinek jest zawsze na końcu drugiego do ostatniego wiersza:
Korzystanie
awk
ibash
Za pomocą
sed
W przypadku OSX i innych platform BSD spróbuj:
Za pomocą
bash
źródło
sed: 1: "x;${s/,$//;p;x}; 2,$ p": extra characters at the end of x command
sed
i często różni się subtelnie. Nie mam dostępu do OSX, aby to przetestować, ale spróbujsed -n -e x -e '${s/,$//;p;x;}' -e '2,$ p' input
Po prostu możesz wypróbować poniższe polecenie jednowierszowe Perla.
Wyjaśnienie:
,
Dopasowuje przecinek.(?!.*,)
Negatywne spojrzenie wstecz zapewnia, że po tym dopasowanym przecinku nie będzie przecinka. Więc pasowałby do ostatniego przecinka.s
A najbardziej importującym jests
modyfikator DOTALL, który sprawia, że kropka pasuje również do znaków nowego wiersza.źródło
perl -0777 -pi -e 's/(.*),(.*?)/\1\2/s'
. Działa to, ponieważ pierwszy.*
jest chciwy, a drugi nie.To powinno usunąć tylko ostatnie wystąpienie
,
dowolnego pliku wejściowego - i nadal będzie drukować te, w których,
nie występuje. Zasadniczo buforuje sekwencje linii, które nie zawierają przecinka.Kiedy napotka przecinek, zamienia bieżący bufor linii z buforem wstrzymania i w ten sposób jednocześnie drukuje wszystkie linie, które wystąpiły od ostatniego przecinka i zwalnia bufor wstrzymania.
Właśnie przeglądałem mój plik historii i znalazłem to:
To jest całkiem niezłe. Tak, używa
eval
, ale nigdy nie przekazuje mu niczego poza odniesieniem numerycznym do swoich argumentów. Buduje dowolnesed
skrypty do obsługi ostatniego dopasowania. Pokażę ci:Wypisuje to na stderr. To jest kopia danych
lmatch
wejściowych:eval
Podskładka ed funkcji iteruje wszystkie argumenty jeden raz. Przechodząc nad nimi, odpowiednio iteruje licznik w zależności od kontekstu dla każdego przełącznika i pomija tak wiele argumentów do następnej iteracji. Odtąd robi jedną z kilku rzeczy na argument:$a
się$o
.$a
jest przypisywany na podstawie wartości,$i
która jest zwiększana o liczbę arg dla każdego przetworzonego arg.$a
ma przypisaną jedną z dwóch następujących wartości:a=$((i+=1))
- jest to przypisywane, jeśli do opcji krótkiej nie dołączono argumentu lub jeśli opcja była długa.a=$i#-?
- to jest przypisany jeśli opcja jest krótka i nie ma jej arg dołączana do niego.a=\${$a}${1:+$d\${$(($1))\}}
- Bez względu na początkowe przypisanie,$a
wartość jest zawsze zawijana w nawiasy klamrowe i - w takim-s
przypadku - czasami$i
jest zwiększana o jeszcze jedno i dołączane jest dodatkowo pole rozdzielane.Powoduje to, że
eval
nigdy nie jest przekazywany ciąg zawierający nieznane. Do każdego z argumentów wiersza polecenia odwołuje się ich numeryczny numer argumentu - nawet separator, który jest wyodrębniany z pierwszego znaku pierwszego argumentu i jest jedynym czasem, w którym powinieneś użyć dowolnego znaku, który jest nieskalowany. Zasadniczo funkcja jest generatorem makr - nigdy nie interpretuje wartości argumentów w żaden specjalny sposób, ponieważsed
może (i oczywiście) z łatwością poradzi sobie z tym podczas analizy skryptu. Zamiast tego rozsądnie układa argumenty w praktyczny skrypt.Oto niektóre dane wyjściowe debugowania funkcji w pracy:
Dzięki temu
lmatch
można łatwo zastosować wyrażenia regularne do danych po ostatnim dopasowaniu w pliku. Wynik polecenia, które uruchomiłem powyżej, to:... który, biorąc pod uwagę podzbiór danych wejściowych pliku, który następuje po ostatnim
/^.0/
dopasowaniu, stosuje następujące podstawienia:sdd&&&&d
- zastępuje$match
się 4 razy.sd'dsqd4
- czwarty pojedynczy cytat następujący po początku wiersza od ostatniego meczu.sd"d\dqd2
- to samo, ale w przypadku podwójnych cytatów i globalnie.Aby więc pokazać, jak można użyć
lmatch
ostatniego przecinka w pliku:WYNIK:
źródło
-m
opcję i uczyniłem ją obowiązkową, przełączyłem się na wiele argumentów dla re i repl dla,-s
a także zaimplementowałem poprawną obsługę separatora. Myślę, że jest kuloodporny. Z powodzeniem użyłem zarówno spacji, jak i pojedynczego cudzysłowu jako separatora,Jeśli przecinek może nie znajdować się w wierszu od drugiego do ostatniego
Korzystanie
awk
itac
:awk
Komenda jest prosta do zrobienia podstawienie za pierwszym razem wzór jest widoczny.tac
odwraca kolejność wierszy w pliku, więcawk
polecenie kończy usuwanie ostatniego przecinka.Powiedziano mi to
może być bardziej wydajny.
źródło
Jeśli możesz użyć
tac
:źródło
widzieć /programming/12390134/remove-comma-from-last-line
To działa dla mnie:
Moim najlepszym sposobem jest usunięcie ostatniej linii i po usunięciu przecinka dodaj ponownie znak]
źródło
Wypróbuj poniżej
vi
:Wyjaśnienie:
$-1
wybierz od drugiej do ostatniej liniis
zastąpić\(,\)\(\_s*]\)
znajdź przecinek, a następnie]
i oddziel je spacjami lub znakiem nowej linii\2
zastąp przez\(\_s*]\)
np. spacje lub znak nowej linii, a następnie]
źródło
Spróbuj z poniższym
sed
poleceniem.źródło