Câu trả lời:
Bạn không thể. Hoặc sử dụng ed hoặc GNU sed hoặc perl, hoặc làm những gì họ làm đằng sau hậu trường, đó là tạo một tệp mới cho nội dung.
ed
, xách tay:
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
, tạo một tệp mới (được khuyến nghị, vì nếu tập lệnh của bạn bị gián đoạn, bạn có thể chạy lại nó):
cut -d , -f 1,3 <foo >foo.new &&
mv -f foo.new foo
cut
, thay thế tệp tại chỗ (giữ quyền sở hữu và quyền của foo
, nhưng cần bảo vệ chống lại sự gián đoạn):
cp -f foo foo.old &&
cut -d , -f 1,3 <foo.old >foo &&
rm foo.old
Tôi khuyên bạn nên sử dụng một trong các cut
phương pháp dựa trên. Bằng cách đó, bạn không phụ thuộc vào bất kỳ công cụ không chuẩn nào, bạn có thể sử dụng công cụ tốt nhất cho công việc và bạn kiểm soát hành vi bị gián đoạn.
cut -d , -f 1,3 foo > foo.new
rm foo
mv foo.new foo
rm foo
. Và bạn không nên gọi rm foo
, bởi vì mv foo.new foo
là nguyên tử: nó loại bỏ phiên bản cũ và đặt phiên bản mới vào vị trí cùng một lúc.
Các moreutils gói từ ubuntu (và cũng debian ) có một chương trình gọi là sponge
, mà sắp xếp của cũng giải quyết được vấn đề của bạn.
Từ người đàn ông bọt biển:
xốp đọc đầu vào tiêu chuẩn và ghi nó ra tập tin được chỉ định. Không giống như chuyển hướng shell, bọt biển thấm tất cả đầu vào của nó trước khi mở tệp đầu ra. Điều này cho phép hạn chế các đường ống đọc và ghi vào cùng một tệp.
Điều này sẽ cho phép bạn làm một cái gì đó như:
cut -d <delim> -f <fields> somefile | sponge somefile
Tôi không nghĩ rằng có thể sử dụng cut
một mình. Tôi không thể tìm thấy nó trong trang thông tin hoặc người đàn ông. Bạn có thể làm một cái gì đó như
mytemp=$(mktemp) && cut -d" " -f1 file > $mytemp && mv $mytemp file
mktemp
làm cho bạn một tệp tạm thời tương đối an toàn mà bạn có thể dẫn cut
đầu ra vào.
Bạn có thể sử dụng slurp với POSIX Awk:
cut -b1 file | awk 'BEGIN{RS="";getline<"-";print>ARGV[1]}' file
Chà, vì cut
tạo ra đầu ra ít hơn nó đọc, bạn có thể làm:
cut -c1 < file 1<> file
Đó là, làm cho stdin của nó file
mở ở chế độ chỉ đọc và stdout của nó file
mở ở chế độ đọc + ghi mà không cắt ( <>
).
Bằng cách đó, cut
sẽ chỉ ghi đè lên tệp. Tuy nhiên, nó sẽ để phần còn lại của tập tin không bị ảnh hưởng. Chẳng hạn, nếu file
chứa:
foo
bar
Đầu ra sẽ trở thành:
f
b
bar
Các f\nb\n
đã thay thế foo\n
, nhưng bar
vẫn còn đó. Bạn cần cắt bớt tệp sau khi cut
hoàn thành.
Với ksh93
, bạn có thể làm điều đó với <>;
toán tử của nó , hoạt động giống như <>
ngoại trừ nếu lệnh thành công, ftruncate()
được gọi trên bộ mô tả tệp. Vì thế:
cut -c1 < file 1<>; file
Với các shell khác, bạn cần thực hiện ftruncate()
thông qua một số phương tiện khác như:
{ cut -c1 < file; perl -e 'truncate STDOUT, tell STDOUT';} 1<> file
mặc dù việc gọi perl
chỉ vì điều đó là quá mức cần thiết ở đây, đặc biệt là xem xét perl
có thể dễ dàng thực hiện cut
công việc đó như:
perl -pi -e '$_ = substr($_, 0, 1)' file
Xin lưu ý rằng với tất cả các phương pháp liên quan đến việc viết lại tại chỗ thực tế, nếu hoạt động bị gián đoạn giữa chừng, bạn sẽ kết thúc với một tệp bị hỏng. Sử dụng một tập tin thứ hai tạm thời để tránh vấn đề này.
.old
phương pháp thay đổi tại chỗ,echo "$(cut -d , -f 1,3 <foo)" > foo