#linux #bash #for-loop #awk #split
#linux #bash #for-цикл #awk #разделить
Вопрос:
У меня есть большой текстовый файл, сохраненный с именем test.txt.Теперь я хочу разделить большие текстовые файлы на блоки по ...
символу и хочу сохранить имя так же, как и то, что есть после /home/niu/
. (В приведенном ниже примере данных мне нужны блоки данных, которые нужно сохранить 20190630_073410_1.5_29_PCK.txt
для первого блока, 20180630_073410_1.5_29_PCK.txt
для второго блока и 20190830_093410_1.5_29_PCK.txt
для третьего блока.
Таким образом, я попробовал приведенный ниже код:
#!/bin/sh
for file in 'test.txt'
do
split -l '...'
done
Это не работает: я надеюсь, что кто-нибудь мне поможет.Спасибо.
Мои данные, сохраненные в test.txt приведено ниже:
...........................................................................................................
/home/niu/20190630_073410_1.5_29_PCK.txt 470.2359935984357 41573823894247.63 53.46648291467124 216 1 0.1
/home/niu/20190630_073410_1.5_29_PCK.txt 13.124782961287574 219608788311302.7 53.46425102814092 219 1 0.6
/home/niu/20190630_073410_1.5_29_PCK.txt 4.092419925137149 12174862157739.746 53.44206693334351 291 1 1.1
...........................................................................................................
/home/niu/20180630_073410_1.5_29_PCK.txt 2.241494955966288 363350265475740.4 53.36874778729164 219 1 0.1
/home/niu/20180630_073410_1.5_29_PCK.txt 1.6671382966847936 282579486756.3921 53.234249504389624 218 1 2.1
/home/niu/20180630_073410_1.5_29_PCK.txt 1.4410832347641427 17729080367.579777 53.06935945567802 216 1 2.6
...........................................................................................................
/home/niu/20190830_093410_1.5_29_PCK.txt 1.2367527642969733 5141.577700615736 52.776493933960644 127 0 3.6
/home/niu/20190830_093410_1.5_29_PCK.txt 1.171644866817557 3279.978138771641 52.65760209064783 135 0 4.1
/home/niu/20190830_093410_1.5_29_PCK.txt 1.120249969361367 2441.45977994814 52.54882982584634 105 0 4.6
Комментарии:
1. упорядочены ли строки в файле по первому столбцу (т.Е. По имени каталога / файла)? у вас действительно есть строки
.................
в файле? все ли строки начинаются с имени каталога / файла и имеют одинаковый формат<directory>/*.*.txt
? учитывая примерный набор входных данных, пожалуйста, обновите свой вопрос желаемым результатом (например, 3x новых файлов? и отобразить содержимое каждого файла)
Ответ №1:
awk '/.../{close(out); next} {split($1, a, "/"); out=a[4]; print > out}' file
Вы можете использовать этот awk. Я предположил, что dots ( ...
) существует только в разделяющих строках, также все остальные строки начинаются с /home/niu/filename.txt
, откуда мы получаем выходное имя файла. Если это не так, пожалуйста, обновите вопрос.
Ответ №2:
вы можете использовать csplit следующим образом:
csplit test.txt '/^./' {*}
Ответ №3:
Не могли бы вы, пожалуйста, попробовать следующее, написанное и протестированное с показанными примерами в GNU awk
.
awk -F'[ /]' '
!NF || /^. /{
next
}
out_file!=$4{
close(out_file)
out_file=$4
}
{
print >> (out_file)
}' Input_file
Объяснение: Добавление подробного объяснения выше.
awk -F'[ /]' ' ##Starting awk program from here and setting space and / for all lines.
!NF || /^. /{ ##Checking condition if number of fields is NULL OR line starting from dot then do following.
next ##next will skip all further statements from here.
}
out_file!=$4{ ##Checking condition if prev is NOT equal to out_file then do following.
close(out_file) ##Closing file in back end to avoid too many files opened error here.
out_file=$4 ##Setting out_file as 4th field here.
}
{
print >> (out_file) ##Printing current line to out_file output file.
}' Input_file ##Mentioning Input_file name here.
РЕДАКТИРОВАТЬ: согласно OP, могут быть строки, начинающиеся с пробелов, поэтому в этом случае попробуйте.
awk -F'/' '
!NF || /^./{
next
}
{
split($4,arr," ")
}
out_file!=arr[1]{
close(out_file)
out_file=arr[1]
}
{
print >> (out_file)
}' Input_file