Contar o número da linha no arquivo txt quando a nova linha estiver dentro dos dados
Eu tenho um arquivo txt que contém os dados abaixo
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"
Agora você pode ver que os dados da minha última coluna têm um novo caractere de linha. então quando eu uso o comando abaixo
awk 'END{print NR}' file.txt
está dando meu comprimento é 15, mas na verdade o comprimento da linha é 3. Por favor, sugira um comando para o mesmo
Parte editada: De acordo com a resposta dada, o script abaixo não está funcionando se não houver nova linha no final do arquivo de entrada
awk -v RS='"[^"]*"' '{gsub(/\n/, " ", RT); ORS=RT} END{print NR "\n"}' test.txt
Além disso, meu arquivo pode ter 3-4 milhões de registros. Portanto, a conversão de arquivos para o formato Unix levará tempo e não é minha preferência. Então, por favor, sugira alguma solução ideal que deve funcionar em ambos os casos
head 5.csv | cat -A
Above command is giving me the output
Nome do URL do celular, texto da mensagem ^ M $
Respostas
Usando, gnu-awkvocê pode fazer isso usando um personalizado RS:
awk -v RS='"[^"]*"' '{gsub(/(\r?\n){2,}/, "\n"); n+=gsub(/\n/, "&")}
END {print n}' <(sed '$s/$//' file)
15001
Aqui:
-v RS='"[^"]*"': Usa este regex como separador de registro de entrada. Que corresponde a uma string entre aspas duplasn+=gsub(/\n/, "&"): Dummy substitui\ncom ele mesmo e conta\nna variávelnEND {print n}: Imprimenno finalsed '$s/$//' file: Para a última linha adiciona uma nova linha (caso esteja faltando)
Demonstração de código
Com perl, supondo que a última linha sempre termine com um caractere de nova linha
$ perl -0777 -nE 'say s/"[^"]+"(*SKIP)(*F)|\n//g' ip.txt
3
-0777para slurp o arquivo de entrada inteiro como uma única string, então isso não é adequado se o arquivo de entrada for muito grande- o
scomando retorna o número de substituições feitas, que é usado aqui para obter a contagem de novas linhas "[^"]+"(*SKIP)(*F)fará com que as novas linhas entre aspas duplas sejam ignoradas
Você pode usar o comando abaixo se quiser contar a última linha, mesmo que ela não termine com um caractere de nova linha.
perl -0777 -nE 'say scalar split /"[^"]+"(*SKIP)(*F)|\n/' ip.txt
O mesmo que anubhava, mas com GNU sed:
<infile sed '/"/ { :a; N; /"$/!ba; s/\n/ /g; }' | wc -l
Resultado:
3