Удалить первую строку файла

110

Как я могу удалить первую строку файла и сохранить изменения?

Я пробовал это, но он стирает все содержимое файла.

$sed 1d file.txt > file.txt
kickass13
источник

Ответы:

81

Причина, по которой файл file.txt пуст после этой команды - порядок, в котором оболочка работает. Первое, что происходит с этой линией, - это перенаправление. Файл "file.txt" открывается и усекается до 0 байт. После этого запускается команда sed, но на данный момент файл уже пуст.

Есть несколько вариантов, большинство из которых включают запись во временный файл.

sed '1d' file.txt > tmpfile; mv tmpfile file.txt # POSIX
sed -i '1d' file.txt # GNU sed only, creates a temporary file

perl -ip -e '$_ = undef if $. == 1' file.txt # also creates a temporary file
jordanm
источник
2
С BSD sedвы можете использовать sed -i .bak '1d' file.txt.
1
Есть ли способ, который не включает временный файл? Во всяком случае, это сделает свое дело. Большое спасибо!
kickass13
@ kickass13 возможно с помощью текстового редактора, такого как ed.
Иордания
6
edКоманда будет: printf "%s\n" 1d w q | ed file.txt(I сердце ред)
Glenn Джекман
1
@jonayreyes-exec sed -i '1d' {} \;
Иордания,
141

Альтернативный очень легкий вариант - просто «хвостить» все, кроме первой строки (обычно это может быть простой способ удаления заголовков файлов):

# -n +2 : start at line 2 of the file.
tail -n +2 file.txt > file.stdout

Следуя @Evan Teitelman, вы можете:

tail -n +2 file.txt | sponge file.txt

Чтобы избежать временного файла. Другой вариант может быть:

echo "$(tail -n +2 file.txt)" > file.txt

И так далее. Тестирование последнего:

[user@work ~]$ cat file.txt
line 1
line 2
line 3
line 4
line 5

[user@work ~]$ echo "$(tail -n +2 file.txt)" > file.txt
[user@work ~]$ cat file.txt
line 2
line 3
line 4
line 5
[user@work ~]$ 

К сожалению, мы потеряли новую строку (за комментарий @ 1_CR ниже), попробуйте вместо этого:

printf "%s\n\n" "$(tail -n +2 file.txt)" > file.txt

[user@work ~]$ cat file.txt
line 1
line 2
line 3
line 4
line 5

[user@work ~]$ printf '%s\n\n' "$(tail -n +2 file.txt)" > file.txt
[user@work ~]$ cat file.txt
line 2
line 3
line 4
line 5  

[user@work ~]$ 

Возвращаясь к sed, попробуйте:

printf '%s\n\n' "$(sed '1d' file.txt)" > file.txt

или возможно

echo -e "$(sed '1d' file.txt)\n" > file.txt

Чтобы избежать побочных эффектов.

AsymLabs
источник
Я только что попробовал это на моей системе Fedora и вывод выше. Вы правы - спасибо за указание на это.
AsymLabs
tailТрюк работал на меня (потребовалось менее 3 секунд на файл 130MB). Спасибо!
elo80ka
echo "$(tail -n +2 file.txt)" > file.txtэто идеальный ответ.
Алекс Радж Калиамурти
Спасибо! echo "$ (tail -n +2 file.txt)"> file.txt у меня работает как шарм!
Арсений
16

Также обратите внимание на spongeс moreutils. spongeвпитывает данные из стандартного ввода до тех пор, пока конец записи стандартного ввода не закроется перед записью в файл. Используется так:

sed '1d' file.txt | sponge file.txt

источник
14

Эта тема представляет интерес, поэтому я тестирую тест в трех направлениях:

  1. sed '1d' d.txt > tmp.txt
  2. tail -n +2 d.txt > tmp.txt
  3. sed -i '1d' d.txt

Обратите внимание, что цель d.txtфайла 5.4 ГБ

Получите результат:


run 1 : sed '1d' d.txt > r1.txt
14s
run 2 : tail -n +2 d.txt > r2.txt
20s
run 3 : sed -i '1d' d.txt
88s

Вывод: кажется ниже будет самый быстрый путь:

sed '1d' file.txt > tmpfile; mv tmpfile file.txt

waue0920
источник
Ваш sed '1d' d.txtметод не включал (или кажется, читая ваши тесты) mvкоманду. В моих тестах на FreeBSD с файлом размером 20 МБ скорость sed -iбыла самой быстрой.
Сопалахо де Арриерес
9

exможет использоваться для истинного редактирования на месте без использования временного файла

ex -c ':1d' -c ':wq' file.txt
Iruvar
источник
2
ex использует временный файл. strace -e open ex -c ':1d' -c ':wq' foo, ex усекает исходный файл с временным файлом, где опция -i в GNU sed перезаписывает исходный файл с временным файлом. Я не уверен, как работает sed BSD.
Луа
@llua, ты прав. Я тоже это заметил, но позже
iruvar
3

Самый короткий и простой способ удалить первую строку из файла с помощью sed:

$ sed -i -n -e '2,$p' file.txt
starfry
источник
3

Вы можете использовать Vim в режиме Ex:

ex -s -c '1d|x' file.txt
  1. 1 найти первую строку

  2. d удалять

  3. x сохранить и закрыть

Стивен Пенни
источник
0

Эта команда удалит 1 строку и сохранит как «file.txt».

sed '1d' file.txt  > /tmp/file.txt && mv /tmp/file.txt file.txt || rm -f /tmp/file.txt
Ритеш Сингх
источник
0

Удалить строку правила в файле

  1. Удалить первую строку

Sed '1d' файл

  1. Удалить первую и третью строку

Sed файл "1d3d"

Удалить персонажа в строке

1 Удалить первые два чартера в Лин

Sed 's /^..//' file

2 Удалите последние две строки

Sed 's / .. £ //' file

3 Удалить пустую строку

Sed '/ ^ £ / d' файл

Вивек парих
источник
4
Британцы захватили колонии? В прошлый раз я смотрел, £$.
G-Man
£ указывал знак доллара ..
Вивек парих
0

Может использовать Vim для этого:

vim -u NONE +'1d' +wq! /tmp/test.txt
Хунбо Лю
источник
-2

кошка file01 | sed -e '1,3d'

// показать содержимое в file01, но удалить первую и третью строку

user215264
источник
2
команда sed, которую вы дадите, удалит строки 1, 2 и 3.
icarus
1
Это удаляет больше, чем запрашивается, и не «сохраняет изменения»
Джефф Шаллер