У меня есть несколько файлов с одинаковым заголовком и разными векторами ниже. Мне нужно объединить их все, но я хочу, чтобы объединялся только заголовок первого файла, и я не хочу, чтобы объединялись другие заголовки, поскольку они все одинаковые.
например: file1.txt
<header>INFO=<ID=DP,Number=1,Type=Integer>
<header>INFO=<ID=DP4,Number=4,Type=Integer>
A
B
C
file2.txt
<header>INFO=<ID=DP,Number=1,Type=Integer>
<header>INFO=<ID=DP4,Number=4,Type=Integer>
D
E
F
Мне нужен выход, чтобы быть
<header>INFO=<ID=DP,Number=1,Type=Integer>
<header>INFO=<ID=DP4,Number=4,Type=Integer>
A
B
C
D
E
F
Я мог бы написать сценарий на R, но мне это нужно в оболочке?
grep
(как в ответе спутника ).head -n 10 file1.txt >output.txt && tail -q -n +11 file*.txt >>output.txt
(если у вас есть 10 строк заголовка). Кроме того, если ваши файлы имеют номера в именах, будьте осторожны, если ониfile9.txt
отсортированы междуfile89.txt
иfile90.txt
. Если ваши файлы номера нравитсяfile001.txt
, ...,files009.txt
,files010.txt
..., тоfiles*.txt
перечислим их в правильном порядке.awk 'FNR==1 && NR!=1{next;}{print}' *.csv
Другое решение, аналогичное "
cat+grep
" сверху, с использованиемtail
иhead
:Запишите заголовок первого файла в вывод:
-
head -2
получает 2 первые строки файла.Добавьте содержимое всех файлов:
-
-n +3
делаетtail
линию печати с 3 - го до конца,-q
говорит ему , чтобы не печатать заголовок с именем файла ( для чтенияman
),>>
добавляет к файлу, а не переписывает его как>
.И, конечно, вы можете поместить обе команды в одну строку:
или вместо того, чтобы
;
поставить&&
между ними для проверки успеха.источник
(head -2 file1.txt ; tail -n +3 -q file*.txt ) > all.txt
или(head -2 file1.txt && tail -n +3 -q file*.txt ) > all.txt
Попробуйте сделать это:
НОТА
-v
означает флаг , чтобы инвертировать матч Grep^
в REGEX означает начало строки:
Это техника нарезки массивов bash .
источник
<header>
строки в любом месте файлов, а не только в начале. Это может не быть проблемой здесь, в зависимости от данных.grep '^<header>' file1.txt >output.txt && grep -v '^<header>' file*.txt >>output.txt
Команда
tail
(по крайней мере в GNU) имеет возможность пропустить заданное количество начальных строк. Для печати начиная со второй строки, т.е. пропустите однострочный заголовок, выполните:tail -n+2 myfile
Итак, чтобы сохранить двухстрочный заголовок первого файла, но не второго, в Bash:
Или для многих файлов:
Если известно, что определенная строка присутствует во всех строках заголовка, но никогда не присутствует в остальных входных файлах,
grep -v
то, как показал спутник , это более простой подход.источник
Короче (не обязательно быстрее) с
sed
:Это удалит все строки, начинающиеся со
<header>...
строки 3, поэтому первый заголовок будет сохранен, а остальные заголовки удалены. Если в заголовке разное количество строк, измените команду соответствующим образом (например, для использования 6-строчного заголовка7
вместо3
).Если количество строк в заголовке неизвестно, вы можете попробовать вот так:
источник
Предполагая, что вы используете папку с файлами .txt с тем же заголовком, который необходимо объединить / объединить, этот код объединит все файлы txt в all.txt с одним заголовком. первая строка (строки, разделенные точкой с запятой) собирает все текстовые файлы для объединения, вторые строки выводят заголовок из первого файла txt в all.txt , а последняя строка объединяет все текстовые файлы, собранные без заголовка (путем запуска конкатенация со строки 2 и далее) и добавляет ее в all.txt .
источник