Пользователь может загружать два типа файлов данных. Пожалуйста, найдите образцы данных ниже
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 New\nDate:27/02/2020\nItems: 1\nTotal: 3\nRegards\nABC DATa\nPh: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
Мне нужна команда, которая будет работать в обоих случаях
@yes мой разделитель полей может быть запятой, вертикальной чертой и табуляцией. Потому что я буду применять ту же команду для txt-файла.
@user13000875 user13000875, извините, но по-прежнему неясна логика вашего ожидаемого результата, как вы его получаете, пожалуйста, более четко упомяните логику получения образца ожидаемого результата в своем вопросе для лучшего понимания вашего вопроса.
@ RavinderSingh13 Я просто хочу получить первые 10 строк файла
@ user13000875, не могли бы вы сообщить нам, если строки, начинающиеся с test, должны быть в одной строке? и пустые строки, а также образец 1 и образец 2 НЕ входят в ожидаемый результат? Пожалуйста, подтвердите это один раз.
@Luuk это не работает
Тег regex использовался OP вместе с awk, sed, и есть веская причина, потому что это решение требует интенсивного использования regex, как видно из вопроса и всех ответов. Пожалуйста, не удаляйте этот тег.





Вы можете попробовать это 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
Можете ли вы преобразовать его в одну строку. Потому что, когда я реализую это внутри своего скрипта, у меня возникают проблемы
Спасибо работает отлично. У вашей команды есть еще одно преимущество: нет зависимости от разделителя
С ГНУ awk:
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
Вы уверены, что это работает? При первом же запуске с NR<=2 он печатает строку заголовка и первую строку 2-й записи, которая является test11 1234567890 www.example.com "Data Test New вместо полной test11 1234567890 www.example.com "Data Test New\nDate:27/02/2020\nItems: 1\nTotal: 3\nRegards\nABC DATa\nPh:091 : 123456789"
@anubhava ты прав. Но ваш ответ работает во всех сценариях. Большое спасибо.
Это может сработать для вас (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
Какой у вас разделитель полей? Несколько пробелов, табуляция или запятая? Вы говорили о CSV.