sed удалить все, кроме первой и последней строки из многих файлов

Я хотел бы обработать много файлов * .txt в каталоге – они имеют общую структуру (разделенные, общие заголовки), но меняются по количеству строк, каждая из которых состоит из одного, а некоторые из них являются одной строкой, другие – до 8 длинные строки ..

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

Обновление: я включил некоторые файлы тестовых данных в соответствии с запросами:

stat87.txt

Stations_id; Stationshoehe; Geogr.Breite; Geogr.Laenge; von_datum; bis_datum; Stationsname; 87; ; 46.1123; 8.5440;19010101;19661229;Dres 

stat01.txt

 Stations_id; Stationshoehe; Geogr.Breite; Geogr.Laenge; von_datum; bis_datum; Stationsname; 1; ; 47.8400; 8.8500;18910101;19580228;Aach 1; 478; 47.8413; 8.8493;19580301;19860630;Aach 

и stat56.txt, например.

 Stations_id; Stationshoehe; Geogr.Breite; Geogr.Laenge; von_datum; bis_datum; Stationsname; 56; ; 46.4580; 7.6320;18980101;19450321;Hamb 56; ; 46.4580; 7.6320;19450321;19880511;Hamb 56; 103; 46.4411; 7.6345;19880601;19990630;Hamb 

В этом случае я был бы особенно заинтересован в том, чтобы сохранить первую строку столбцов 5 и последнюю из столбца 6, чтобы захватить временной интервал станции.

Результаты:

 find . -type f -name \*.txt -printf "%f\0" | xargs -0 -I xxxx sed -ni ' 2 { $ { s/^[^;]*;[^;]*;[^;]*;[^;]*;\([^;]*\);\([^;]*\).*$/\1;\2/ p q } s/^[^;]*;[^;]*;[^;]*;[^;]*;\([^;]*\).*$/\1/ p } $ { s/^[^;]*;[^;]*;[^;]*;[^;]*;[^;]*;\([^;]*\).*$/\1/ p }' xxxx 

создает ….

 19010101;19661229 18910101 19860630 18980101 19990630 

Затем я использую простой цикл sed, чтобы очистить финальные файлы, добавив;

 'for file in *.txt; do sed 'N;s/\n/;/' "$file" > "cleaned$file" done' 19010101;19661229 18910101;19860630 18980101;19990630 

3 Solutions collect form web for “sed удалить все, кроме первой и последней строки из многих файлов”

Идеально, есть ниже версии awk:

 find . -type f -name \*.txt -printf "%f\0" | xargs -0 -I xxxx sed -ni ' 2 { $ { s/^[^;]*;[^;]*;[^;]*;[^;]*;\([^;]*\);\([^;]*\).*$/\1;\2/ p q } s/^[^;]*;[^;]*;[^;]*;[^;]*;\([^;]*\).*$/\1/ h } $ { s/^[^;]*;[^;]*;[^;]*;[^;]*;[^;]*;\([^;]*\).*$/\1/ H x s/\n/;/ p }' xxxx 

Спасибо вам, очень известный Sed – введение и учебник от Брюса Барнетта

Результаты:

 $ cat stat01.txt 18910101;19860630 $ cat stat56.txt 18980101;19990630 $ cat stat87.txt 19010101;19661229 

—-


первая версия для справки

Основываясь на ваших данных, я придумал формат файла данных и сценарий sed для их работы.

Попробуйте:

 $ find . -type f -name \*.txt -printf "%f\0" | xargs -0 -I xxxx sed -ni ' 2 { $ { s/^[^;]*;\([^;]*\);\([^;]*\).*$/\1;\2/ p q } s/^[^;]*;\([^;]*\).*$/\1/ p } $ { s/^[^;]*;[^;]*;\([^;]*\).*$/\1/ p }' xxxx 

Он удаляет первую строку, содержащую заголовки.

Он содержит только столбец 2 первой строки данных и столбец 3 последней строки данных файла.

Если файл содержит только одну строку данных, он удерживает один столбец строки 2 и столбец 3.

hehehe это странно, но мне было очень весело!

Файлы данных в текущем каталоге:

 $ cat test01.txt Name;Price;Amount;Description Bread;2.1;3;healthy one $ cat test02.txt Name;Price;Amount;Description Water;0.0;100;For life Wine;10.3;1;Less than half a glass a day $ cat test03.txt Name;Price;Amount;Description House;1000.0;1;home Car;500.5;0;no need Bike;10.3;5;Good for the planet and for me 

Результаты:

 $ cat test01.txt 2.1;3 $ cat test02.txt 0.0 1 $ cat test03.txt 1000.0 5 

Укажите два коротких файла данных и ожидаемый результат, и я изменю этот ответ.

Для этого вам понадобится цикл:

 for file in *.txt; do lines=$(wc -l < "$file") if [ "$lines" -lt 3 ]; then echo "$file is short enough, not touching it." else # for testing, you can also use the -i option sed -n '1p;$p' "$file" > "$file.new" fi done 

Цикл необходим, если у вас есть файлы длиной всего одна строка. С командой, заданной thrig, они появятся дважды (попробуйте echo 1|sed -n '1p;$p' ).

Gawk – намного лучший инструмент для этой задачи, чем sed. Повторное использование конвейера find-xargs исходного подхода и использование той же выходной номенклатуры:

 find . -type f -name \*.txt -printf "%f\0" | xargs -0 gawk -F\; ' FNR==2 { von = $5 } ENDFILE { print von FS $6 > "cleaned" FILENAME } ' 

Код делается намного проще, намного понятнее и в высшей степени удобнее.

  • Как сравнить столбцы одной строки в одном файле?
  • Несколько команд sed в файле
  • Извлечение нескольких данных из столбца с помощью sed
  • Получите строку и поместите ее в начале строки, пока не будет найдена следующая строка
  • Создание нескольких входных файлов с помощью sed в цикле for
  • Извлечь определенный текст из переменной в сценарии оболочки
  • Лишь оставлять самую длинную линию, когда первая колонка дублируется
  • Как заменить пробелы в именах файлов с помощью подчеркивания
  • Объединение цикла вокруг команды sed обрабатывает многие файлы в одном каталоге
  • Удалите строку из определенного поля с помощью awk / sed
  • Используйте sed для выбора потенциально многострочной записи журнала
  • Linux и Unix - лучшая ОС в мире.