我想找到文件中的最后一行文本,并删除其末尾的逗号。我已经问过这个问题了,但是,在得到答案后,我意识到我的问题不够具体。
该sed
命令将转到文件的最后一行并对其执行操作。就我而言,我想删除结尾的逗号:
sed -i '$ s/",/"/g' file.txt
Run Code Online (Sandbox Code Playgroud)
所以这:
blah blah blah,
blah blah blah,
blah blah blah,
Run Code Online (Sandbox Code Playgroud)
...变成这样:
blah blah blah,
blah blah blah,
blah blah blah
Run Code Online (Sandbox Code Playgroud)
但是,如果文件中最后一行文本后面有空行,则此方法将不起作用。
我一直在寻找获取最后一行文本的方法,但还没有想出任何我可以理解和应用的方法。我还寻找了删除所有尾随空白行的方法,并找到了以下命令:
sed -e :a -e '/^\n*$/{$d;N;ba' -e '}' *.txt
Run Code Online (Sandbox Code Playgroud)
但它对我不起作用(它似乎只是在命令行上输出我的文件的内容)。无论如何,这都是不优雅的。我不想删除尾随的空白行,最好只识别最后一行包含文本的内容并对其采取行动。
如何删除目录中多个文件的最后一行文本中的逗号?
对于大文件,使用 Guru 的答案,速度更快。然而,在小文件(<25 行)上,我发现这稍微快一些(假设您有 GNU tac):
tac file | awk '!/^[[:blank:]]*$/{i++;if(i==1){sub(",$","")}}1' | tac
Run Code Online (Sandbox Code Playgroud)
回答
perl -0777 -p -i -e 's/,(\n*)\Z/\1/m' *.txt
Run Code Online (Sandbox Code Playgroud)
将删除所有以 结尾的文件中的最后一个 ',' .txt
,如果 ',' 后面仅跟有 0 个或多个换行符,然后是文件末尾。
从你的例子来看:
reedm@www:~/tmp $ cat > test.txt
blah blah blah,
blah blah blah,
blah blah blah,
reedm@www:~/tmp $ perl -0777 -p -i -e 's/,(\n*)\Z/\1/m' *.txt
reedm@www:~/tmp $ cat test.txt
blah blah blah,
blah blah blah,
blah blah blah
reedm@www:~/tmp $
Run Code Online (Sandbox Code Playgroud)
什么?
即使在最好的情况下,Perl 也是一头深奥的野兽,而 Perl 的俏皮话可能特别神秘。
该-e
标志允许我们在命令行上传递 perl 程序。在本例中,“s/regex/replace/flags”就是程序。
该-p
标志使 perl 在循环中对所提供的每个文件名的每个“行”(请参阅 参考资料)应用您提供的程序-0
。
该-i
标志使 perl 用程序的输出替换文件,而不是将输出打印到标准输出。
该-0
标志更改 perl 用于将文件分成“行”的分隔符。0777
是一个特殊值,按照惯例使用它使 perl 将整个文件读取到单个“行”中。
由于使用了一些特定于 Perl 的技巧,正则表达式有些复杂:
m
末尾的标志导致正则表达式在多行上运行。,
很简单,并且匹配单个逗号。(\n*)
匹配一行中的 0 个或多个换行符,并将它们存储为子模式((
和)
字符表示子模式)。由于这是第一个子模式,我们可以\1
在替换部分中使用它来表示“无论该子模式匹配什么”。\Z
是 Perl 特定的扩展名,并且匹配正在使用的字符串的结尾——在本例中,这是整个文件。\1
一系列换行符替换匹配项,并删除逗号。有关 perl 正则表达式和 perl 命令行标志的 man 信息,请分别查看perlre
和 的手册页perlrun
。