Cuente el número de línea en el archivo txt cuando la nueva línea está dentro de los datos

Nov 27 2020

Tengo un archivo txt que tiene los siguientes datos

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"

Ahora puede ver que los datos de mi última columna tienen un carácter de nueva línea. así que cuando uso el siguiente comando

awk 'END{print NR}' file.txt

está dando que mi longitud es 15 pero en realidad la longitud de la línea es 3. Sugiera un comando para el mismo

Parte editada: según la respuesta dada, el script a continuación no funciona si no hay una nueva línea al final del archivo de entrada

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

También mi archivo puede tener 3-4 millones de registros. Así que convertir el archivo a formato Unix llevará tiempo y esa no es mi preferencia. Por lo tanto, sugiera una solución óptima que debería funcionar en ambos casos

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

Nombre del texto del mensaje de URL móvil ^ M $

Respuestas

7 anubhava Nov 27 2020 at 09:49

Usando gnu-awkpuede hacer esto usando un personalizado RS:

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

15001

Aquí:

  • -v RS='"[^"]*"': Utiliza esta expresión regular como separador de registros de entrada. Que coincide con una cadena entre comillas dobles
  • n+=gsub(/\n/, "&"): Dummy se reemplaza \npor sí mismo y cuenta \nen variablen
  • END {print n}: Imprime nal final
  • sed '$s/$//' file: Para la última línea agrega una nueva línea (en caso de que falte)

Demostración de código

1 Sundeep Nov 27 2020 at 10:14

Con perl, asumiendo que la última línea siempre termina con un carácter de nueva línea

$ perl -0777 -nE 'say s/"[^"]+"(*SKIP)(*F)|\n//g' ip.txt
3
  • -0777 para absorber todo el archivo de entrada como una sola cadena, por lo que esto no es adecuado si el archivo de entrada es muy grande
  • el scomando devuelve el número de sustituciones realizadas, que se utiliza aquí para obtener el recuento de nuevas líneas
  • "[^"]+"(*SKIP)(*F) hará que se ignoren las nuevas líneas entre comillas dobles

Puede usar el siguiente comando si desea contar la última línea incluso si no termina con un carácter de nueva línea.

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

Igual que anubhava pero con GNU sed:

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

Salida:

3