man
Сторінка не дає мені великі надії, але я сподіваюся , що це документований (і / або GNU-специфічних) функція.
man
Сторінка не дає мені великі надії, але я сподіваюся , що це документований (і / або GNU-специфічних) функція.
Відповіді:
Ви не можете. Або використовуйте ed або GNU sed або perl, або робіть те, що вони роблять за кадром, це створити новий файл для вмісту.
ed
, портативний:
ed foo <<EOF
1,$s/^\([^,]*\),\([^,]*\),\([^,]*\).*/\1,\3/
w
q
EOF
GNU sed
:
sed -i -e 's/^\([^,]*\),\([^,]*\),\([^,]*\).*/\1,\3/' foo
Perl:
perl -i -l -F, -pae 'print @F[1,3]' foo
cut
, створивши новий файл (рекомендується, оскільки якщо ваш сценарій буде перервано, ви можете просто запустити його знову):
cut -d , -f 1,3 <foo >foo.new &&
mv -f foo.new foo
cut
, замінюючи файл на місці (зберігає право власності та дозволи foo
, але потребує захисту від перебоїв):
cp -f foo foo.old &&
cut -d , -f 1,3 <foo.old >foo &&
rm foo.old
Я рекомендую використовувати один із cut
методів на основі. Таким чином, ви не залежите від будь-якого нестандартного інструменту, ви можете використовувати найкращий інструмент для роботи та контролювати поведінку при перериванні.
cut -d , -f 1,3 foo > foo.new
rm foo
mv foo.new foo
rm foo
. І не варто дзвонити rm foo
, бо mv foo.new foo
атомний: він видаляє стару версію і одночасно ставить нову версію.
Пакет moreutils від ubuntu (а також debian ) має програму під назвою sponge
, яка також вирішує вашу проблему.
Від чоловічої губки:
губка зчитує стандартне введення та записує його у вказаний файл. На відміну від перенаправлення оболонки, губка вбирає весь її вхід до відкриття вихідного файлу. Це дозволяє звужувати трубопроводи, які читаються з та записуються в один і той же файл.
Що дозволить вам зробити щось на кшталт:
cut -d <delim> -f <fields> somefile | sponge somefile
Я не думаю, що це можливо cut
самостійно. Я не зміг його знайти на сторінці "людина" чи "Інформація". Можна зробити щось таке, як
mytemp=$(mktemp) && cut -d" " -f1 file > $mytemp && mv $mytemp file
mktemp
робить вас відносно безпечним тимчасовим файлом, в який ви можете cut
передавати вихід.
Ви можете використовувати slurp за допомогою POSIX Awk:
cut -b1 file | awk 'BEGIN{RS="";getline<"-";print>ARGV[1]}' file
Ну, оскільки cut
отримує менше результатів, ніж читає, ви можете:
cut -c1 < file 1<> file
Тобто, зробіть його stdin file
відкритим у режимі лише для читання, а його stdout - file
відкритим у режимі читання + запису без укорочення ( <>
).
Таким чином, cut
буде просто перезаписати файл над собою. Однак він залишить решту файлів недоторканими. Наприклад, якщо він file
містить:
foo
bar
Вихід стане:
f
b
bar
f\nb\n
Замінили foo\n
, але bar
все ж є. Вам потрібно буде обрізати файл після cut
його закінчення.
З ksh93
, ви можете зробити це з його <>;
оператором, який діє як, <>
за винятком випадків, якщо команда успішна, ftruncate()
викликається в дескрипторі файлів. Так:
cut -c1 < file 1<>; file
З іншими оболонками вам потрібно буде скористатися ftruncate()
іншими засобами, такими як:
{ cut -c1 < file; perl -e 'truncate STDOUT, tell STDOUT';} 1<> file
хоча звернення perl
лише до цього трохи непосильне, особливо враховуючи, що perl
це легко виконати таку cut
роботу, як:
perl -pi -e '$_ = substr($_, 0, 1)' file
Будьте уважні, що з усіма методами, які передбачають фактичне переписування на місці, якщо операція перервана на середині, ви отримаєте пошкоджений файл. Використання тимчасового другого файлу дозволяє уникнути цієї проблеми.
.old
метод змін на місці,echo "$(cut -d , -f 1,3 <foo)" > foo