Ответы:
Причина, по которой файл 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
ed
.
ed
Команда будет: printf "%s\n" 1d w q | ed file.txt
(I сердце ред)
-exec sed -i '1d' {} \;
Альтернативный очень легкий вариант - просто «хвостить» все, кроме первой строки (обычно это может быть простой способ удаления заголовков файлов):
# -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
Чтобы избежать побочных эффектов.
tail
Трюк работал на меня (потребовалось менее 3 секунд на файл 130MB). Спасибо!
echo "$(tail -n +2 file.txt)" > file.txt
это идеальный ответ.
Также обратите внимание на sponge
с
moreutils
. sponge
впитывает данные из стандартного ввода до тех пор, пока конец записи стандартного ввода не закроется перед записью в файл. Используется так:
sed '1d' file.txt | sponge file.txt
Эта тема представляет интерес, поэтому я тестирую тест в трех направлениях:
sed '1d' d.txt > tmp.txt
tail -n +2 d.txt > tmp.txt
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
sed '1d' d.txt
метод не включал (или кажется, читая ваши тесты) mv
команду. В моих тестах на FreeBSD с файлом размером 20 МБ скорость sed -i
была самой быстрой.
ex
может использоваться для истинного редактирования на месте без использования временного файла
ex -c ':1d' -c ':wq' file.txt
strace -e open ex -c ':1d' -c ':wq' foo
, ex усекает исходный файл с временным файлом, где опция -i в GNU sed перезаписывает исходный файл с временным файлом. Я не уверен, как работает sed BSD.
Вы можете использовать Vim в режиме Ex:
ex -s -c '1d|x' file.txt
1
найти первую строку
d
удалять
x
сохранить и закрыть
Эта команда удалит 1 строку и сохранит как «file.txt».
sed '1d' file.txt > /tmp/file.txt && mv /tmp/file.txt file.txt || rm -f /tmp/file.txt
Удалить строку правила в файле
Sed '1d' файл
Sed файл "1d3d"
Удалить персонажа в строке
1 Удалить первые два чартера в Лин
Sed 's /^..//' file
2 Удалите последние две строки
Sed 's / .. £ //' file
3 Удалить пустую строку
Sed '/ ^ £ / d' файл
£
≠ $
.
кошка file01 | sed -e '1,3d'
// показать содержимое в file01, но удалить первую и третью строку
sed
вы можете использоватьsed -i .bak '1d' file.txt
.