Policz liczbę linii w pliku txt, gdy nowa linia znajduje się w danych

Nov 27 2020

Mam jeden plik txt, który zawiera poniższe dane

Name    mobile  url message text
test11  1234567890  www.google.com  "Data Test New
Date:27/02/2020
Items: 1
Total: 3
Regards
ABC DATa
Ph:091 : 123456789"
test12  1234567891  www.google.com  "Data Test New one
Date:17/02/2020
Items: 26
Total: 5
Regards
user test
Ph:091 : 433333333"

Teraz możesz zobaczyć, że moje dane ostatniej kolumny mają nowy znak linii. więc kiedy używam poniższego polecenia

awk 'END{print NR}' file.txt

to daje moją długość to 15, ale w rzeczywistości długość linii to 3. Proszę zasugerować polecenie dla tego samego

Część edytowana: Zgodnie z odpowiedzią podaną poniżej skrypt nie działa, jeśli na końcu pliku wejściowego nie ma nowej linii

awk -v RS='"[^"]*"' '{gsub(/\n/, " ", RT); ORS=RT} END{print NR "\n"}' test.txt 

Również mój plik może zawierać 3-4 miliony rekordów. Więc konwersja pliku do formatu unix zajmie trochę czasu i nie jest to moje preferencje. Dlatego prosimy o zaproponowanie optymalnego rozwiązania, które powinno działać w obu przypadkach

head 5.csv | cat -A  
Above command is giving me the output

Nazwij tekst wiadomości mobilnego adresu URL ^ M $

Odpowiedzi

7 anubhava Nov 27 2020 at 09:49

Używając gnu-awkmożesz to zrobić za pomocą niestandardowego RS:

awk -v RS='"[^"]*"' '{gsub(/(\r?\n){2,}/, "\n"); n+=gsub(/\n/, "&")}
END {print n}' <(sed '$s/$//' file)

15001

Tutaj:

  • -v RS='"[^"]*"': Używa tego wyrażenia regularnego jako separatora rekordów wejściowych. Który pasuje do ciągu w cudzysłowie
  • n+=gsub(/\n/, "&"): Dummy zamienia \nsię na siebie i liczy się \nw zmiennejn
  • END {print n}: Wydruki nna końcu
  • sed '$s/$//' file: Dla ostatniej linii dodaje nową linię (w przypadku jej braku)

Code Demo

1 Sundeep Nov 27 2020 at 10:14

Przy perlzałożeniu, że ostatnia linia zawsze kończy się znakiem nowej linii

$ perl -0777 -nE 'say s/"[^"]+"(*SKIP)(*F)|\n//g' ip.txt
3
  • -0777 do slurp całego pliku wejściowego jako pojedynczego ciągu, więc nie jest to odpowiednie, jeśli plik wejściowy jest bardzo duży
  • sliczba powraca dowodzenia podstawień wykonane, który jest używany tutaj, aby uzyskać liczbę nowych linii
  • "[^"]+"(*SKIP)(*F) spowoduje, że znaki nowej linii w podwójnych cudzysłowach będą ignorowane

Możesz użyć poniższego polecenia, jeśli chcesz policzyć ostatnią linię, nawet jeśli nie kończy się ona znakiem nowej linii.

perl -0777 -nE 'say scalar split /"[^"]+"(*SKIP)(*F)|\n/' ip.txt
Thor Nov 27 2020 at 13:10

To samo co anubhava, ale z sedem GNU:

<infile sed '/"/ { :a; N; /"$/!ba; s/\n/ /g; }' | wc -l

Wynik:

3