Я пытаюсь объединить несколько файлов с помощью следующей команды:

copy test1.txt+test2.txt test3.txt

Это работает очень хорошо, однако, файлы, которые я пытаюсь объединить, содержат записи заголовка в начале каждого. Можно ли использовать команду, чтобы исключить первую строку в текстовом файле и объединить только остальные?

РЕДАКТИРОВАТЬ: Конечная цель состоит в том, чтобы объединить шесть файлов .txt, содержащих сотни тысяч записей в один файл.

2 ответа2

3

Следующее хорошо работает из командной строки для большинства обстоятельств

(for %F in (test1.txt test2.txt) do @more +1 "%%F") >test3.txt

Удвойте проценты, если вы используете команду в пакетном скрипте.

Вышеуказанное имеет следующие ограничения

  • Каждый исходный файл должен иметь менее 64 тыс. Строк, иначе он будет зависать.
  • Любые символы табуляции будут преобразованы в строку пробелов
  • Я думаю, что есть, по крайней мере, еще одно ограничение, но моя память не работает (возможно, нулевые байты преобразованы в новую строку ??)



Следующий пакетный скрипт не имеет ограничений, за исключением того, что длина каждой строки должна быть менее 8 КБ. Но это, вероятно, слишком медленно для больших файлов (пакет является паршивым инструментом для обработки текста):
@echo off
setlocal disableDelayedExpansion
>test3.txt (
  for %%F in (test1.txt test2.txt) do for /f "skip=1 delims=" %%A in (
    'findstr /n "^" "%%F"'
  ) do (
    set "ln=%%A"
    setlocal enableDelayedExpansion
    echo(!ln:*:=!
    endlocal
  )
)



Вы могли бы написать собственный скрипт JScript или VB, который мог бы сделать это эффективно.

Моя гибридная утилита JScript/batch JREPL.BAT справится с этой задачей . Это излишне, но эффективно справится с работой даже с очень большими файлами.

JREPL.BAT - это текстовый процессор общего назначения с множеством опций. Это чистый скрипт, который запускается изначально на любой машине с Windows начиная с XP.

Следующее будет работать в командной строке.

>test3.txt (for %F in (test1.txt test2.txt) do @JREPL "^.*" "ln>1?$0:false" /jmatch /f "%F")

Если вы используете пакетный скрипт, вы должны использовать CALL JREPL и удвоить проценты:

@echo  off
>test3.txt (for %%F in (test1.txt test2.txt) do call JREPL "^.*" "ln>1?$0:false" /jmatch /f "%%F")
1

Если все заголовки в одной строке, вы можете использовать for file in test*.txt ; do cat $file | sed '1d;$d' ; done > output.file

Объяснение:

for variable in pattern используется bash в цикле for.
Самый простой способ продемонстрировать это for a in * ; do echo $a; done которое перечислит все файлы (и, возможно, папку) в текущем каталоге.

Выходные данные передаются через sed (потоковый редактор) с помощью команды для удаления первой строки (при условии, что ваши заголовки имеют длину только одну строку).

> output_file должен быть очевидным.

Я уверен, что есть гораздо более продвинутые методы. Например, используйте find с -type f, чтобы получить только файлы. Но в крайнем случае это очень простое решение, использующее только bash, sed и cat (и вы явно пометили его как bash и попросили, чтобы что-то было согласовано).


Редактировать: Как указано, этот синтаксис похож на Windows. Таким образом, платформа может быть окнами.

В этом случае посмотрите на этот пост о переполнении стека и ответе, который содержит FOR /F "tokens=* skip=1" %A IN ('type "input_file.ext"') DO @echo %A>>"output_file.ext"

Они ключ больше +1

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .