ファイルの末尾の-WORをVWORに置き換える必要があります。
頑張りました
sed s/WOR/VWOR/g
しかし、これはファイルに新しい空行があるまで機能しません。
だから私は使用しました
( cat FileName && echo ) | sed 's/WOR/VWOR/g'
これはうまくいきます。しかし、sedはファイル全体を読んでいるので、交換に時間がかかります。
答え1
ファイルが新しい行で終わっていることを確認してください。これは「テキストファイル」の要件です。
[ -n $(tail -c1 FileName) ] && printf '\n' >> FileName
末尾の改行は必要なときだけ追加されるため、何度でも問題はなく、最後の文字だけを確認するので、速度が非常に高速です。
次に、(現在有効な)最後の行($)を変更します。
sed -ie '$s/WOR/VWOR/'
注:このコマンドはシンボリックリンクを物理ファイルに変換します。
答え2
まあ、私はsed / awkや他の方法でこの問題を解決する方法を知りません。これはCで書かれており、高速です。
/*
by Hans Schou <[email protected]> 2016
Use on your own risk.
vim: ts=4 :
gcc -o replacelastline replacelastline.c && ./replacelastline WOR VWOR Filename V
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#define SEARCH 1
#define REPLACE 2
#define FILENAME 3
#define VERBOSE 4
int main(int argc, char *argv[]) {
if (FILENAME >= argc) {
printf("Error, too few args. Only found %d.\n", argc);
return EXIT_FAILURE;
}
printf("argc %d.\n", argc);
int V = 0;
if (VERBOSE <= argc) {
V = 'V' == argv[VERBOSE][0] ? 1 : 0;
printf("Verbose: %d\n", V);
}
if (V) {
printf("argv[SEARCH]: %d %s\n", strlen(argv[SEARCH]), argv[SEARCH]);
printf("argv[REPLACE]: %d %s\n", strlen(argv[REPLACE]), argv[REPLACE]);
printf("argv[FILENAME]: %s\n", argv[FILENAME]);
printf("Open file: %s\n", argv[3]);
}
size_t newFileSize = 0;
FILE *fp = fopen(argv[FILENAME],"r+");
if (NULL == fp) {
fprintf(stderr, "Error open file: %s\n", argv[FILENAME]);
return EXIT_FAILURE;
} else {
char inpBuf[8192];
/* Seek to end-of-file minus buffer size */
if (0 == fseek(fp, -sizeof(inpBuf), SEEK_END)) {
/* Read buffer with last part of file */
if (sizeof(inpBuf) != fread(&inpBuf, 1, sizeof(inpBuf), fp)) {
fprintf(stderr, "Error, could not read %d bytes from '%s'\n", sizeof(inpBuf), argv[FILENAME]);
return EXIT_FAILURE;
} else {
/* In the inpBuf, search backwards where the last line start */
int i = sizeof(inpBuf)-1-1; /* one extra minus-1 if last char is '\n' */
while (i && '\n' != inpBuf[i-1]) {
--i;
}
newFileSize = ftell(fp) - sizeof(inpBuf) + i;
if (V) printf("Last line number of chars: %d\n", sizeof(inpBuf)-i);
if (V) printf("The line: '%*.*s'\n", 10, sizeof(inpBuf)-i, &inpBuf[i]);
/* Seek back in the file to where the last line starts */
if (0 == fseek(fp, -(sizeof(inpBuf)-i), SEEK_END)) {
if (V) printf("Pos start last line: %d\n", ftell(fp));
char outBuf[sizeof(inpBuf)];
int o = 0;
/* Read inpBuf and copy to outBuf. If SEARCH found replace with REPLACE */
while (sizeof(inpBuf) > i) {
if (0 != strncmp(&inpBuf[i], argv[SEARCH], strlen(argv[SEARCH]))) {
outBuf[o] = inpBuf[i];
++i;
++o;
} else {
memcpy(&outBuf[o], argv[REPLACE], strlen(argv[REPLACE]));
i += strlen(argv[SEARCH]);
o += strlen(argv[REPLACE]);
}
}
newFileSize += o;
if (V) printf("New line: '%*.*s'\n", o, o, &outBuf);
size_t bytesWritten = fwrite(&outBuf, 1, o, fp);
if (o != bytesWritten) {
fprintf(stderr, "Error, should write %d bytes, but wrote %zu bytes.\n", o, bytesWritten);
return EXIT_FAILURE;
}
}
}
}
fclose(fp);
/* if file should be smaller than before then truncate */
if (newFileSize && strlen(argv[SEARCH]) > strlen(argv[REPLACE])) {
if (V) printf("New file size: %zu\n", newFileSize);
truncate(argv[FILENAME], newFileSize);
}
}
return EXIT_SUCCESS;
}
答え3
以下を使用して、ファイルの末尾の空白行を削除し、ファイルにいくつかのテキストを追加できます。
(sed -e :a -e '/^\n*$/{$d;N;ba' -e '}' "${FILE_NAME}" | sed '$d' && echo "Hello") > "${NEW_FILE_NAME}"
sed -e :a -e '/^\n*$/{$d;N;ba' -e '}'
:ファイルの末尾の空白行をすべて削除します。
sed '$d'
:最後の行が削除されます。
echo "Hello"
:テキストが追加されます。