用户可以上传两种类型的文件数据。请在下面找到样本数据
Sample 1:
Name mobile url message text
test11 1234567890 www.example.com "Data Test New
Date:27/02/2020
Items: 1
Total: 3
Regards
ABC DATa
Ph:091 : 123456789"
test12 1234567891 www.example.com hello
Sample2
test12 1234567891 www.example.com hello
test13 1234567892 www.example.com hi
test14 1234567893 www.example.com hi
用户文件可以有2-3百万条记录。所以我想给用户预览选项,用户可以预览他们上传文件的前10行。为了获得前10行,我正在使用以下命令
awk -v RS='"[^"]*"' 'NR>10{exit} {gsub(/r?n/, "\n", RT); ORS=RT} 1' test.csv
当文件行具有双倍值时,它可以完美地工作,但对于示例2,它将打印文件中的所有记录。
以下命令适用于样本2,但不适用于样本1
head -n10 test.csv | tr '^' ','
排除输出:
Sample1:
Name mobile url message text
test11 1234567890 www.example.com "Data Test NewnDate:27/02/2020nItems: 1nTotal: 3nRegardsnABC DATanPh:091 : 123456789"
test12 1234567891 www.example.com hello
Sample 2:
test12 1234567891 www.example.com hello
test13 1234567892 www.example.com hi
test14 1234567893 www.example.com hi
我需要一个在两种情况下都能工作的命令
您可以尝试此gnu awk
:
awk -v RS='("[^"]*")?r?n' 'NF {
ORS = gensub(/r?n(.)/, "\\n\1", "g", RT)
++n
print
}
n == 10 {exit}' file
或者一行:
awk -v RS='("[^"]*")?r?n' 'NF{ORS = gensub(/r?n(.)/, "\\n\1", "g", RT); ++n; print} n==2{exit}' file
使用GNUawk
:
awk 'BEGIN{
FS="[t,|]" # field separators: tab, comma and pipe
RS="r{0,1}n" # input record separator
}
$NF~/^"/ && $NF~/[^"]$/{ # if last field starts with " but does not end with "
m=$0 # build new row in variable m
while ($0~/[^"]$/){ # loop until current row does not end with "
getline # read next row
m=m "\n" $0 # append current row to variable m
NR-- # decrease the row counter
}
$0=m # copy new build row to current row
}
NR<=10{print}' file
作为一行:
awk 'BEGIN{FS="[t,|]"; RS="r{0,1}n"} $NF~/^"/ && $NF~/[^"]$/ {m=$0; while ($0~/[^"]$/){getline; m=m "\n" $0; NR--}; $0=m} NR<=10{print}' file
参见:8个强大的Awk内置变量–FS、OFS、RS,ORS、NR和NF以及FILENAME、FNR
这可能对你有用(GNU sed(:
sed -E '/^([^"]*"[^"]*")*[^"]*"[^"]*$/{
:a;N;//ba;s/n/\n/g};x;s/^/x/;/x{10}/{x;q};x' file
解决方案分为两半:
- 第一部分连接引号不平衡的连续行
- 第二部分统计打印的行数
第一部分,追加行,直到双引号平衡(如果没有引号,则不平衡(。然后用\n
替换换行符。
第二部分使用保持空间来维持计数器(在解决方案10中(,该计数器在到达时终止处理。
注意:每个文件只能调用一次。要一次处理多个文件,请使用:
sed -nsE '/^([^"]*"[^"]*")*[^"]*"[^"]*$/{:a;N;//ba;s/n/\n/g};p
x;s/^/x/;/x{10}/{:b;n;bb};x' file1 file2 ... filen