卸下文件中的特定行但不使用awk或者sed [英] Remove a specific line from a file WITHOUT using sed or awk
问题描述
我需要从使用bash脚本文件删除特定的行号。
I need to remove a specific line number from a file using a bash script.
我从使用-n选项grep命令的行号。
I get the line number from the grep command with the -n option.
我不能用sed为各种原因,其中最重要的是,它不是安装在所有这脚本需要上运行的系统和安装它不是一个选项。
I cannot use sed for a variety of reasons, least of which is that it is not installed on all the systems this script needs to run on and installing it is not an option.
AWK是不可能的,因为在测试中,与不同的UNIX / Linux操作系统的(RHEL,在SunOS,Solaris和Ubuntu的,等等),它给(有时疯狂)在每个不同的结果不同的机器。所以,没有AWK。
awk is out of the question because in testing, on different machines with different UNIX/Linux OS's (RHEL, SunOS, Solaris, Ubuntu, etc.), it gives (sometimes wildly) different results on each. So, no awk.
有问题的文件只是一个纯文本文件,每行一个记录,所以没有什么特别的事情要做,除了由数字删除就行了。
The file in question is just a flat text file, with one record per line, so nothing fancy needs to be done, except for remove the line by number.
如果可能的话,我需要避免做类似提取内容的文件,不包括我想要走了线,然后覆盖原文件。
If at all possible, I need to avoid doing something like extracting the contents of the file, not including the line I want gone, and then overwriting the original file.
推荐答案
既然你有的grep
,明显的事情是:
Since you have grep
, the obvious thing to do is:
$ grep -v "line to remove" file.txt > /tmp/tmp
$ mv /tmp/tmp file.txt
$
但它听起来像是你不希望使用任何临时文件 - 我假定输入文件很大,这是一个嵌入式系统,内存和存储都供不应求。我想你最好需要一个编辑该文件到位的解决方案。我想这可能是可能的 DD
,但还没有想通出来呢:(
But it sounds like you don't want to use any temporary files - I assume the input file is large and this is an embedded system where memory and storage are in short supply. I think you ideally need a solution that edits the file in place. I think this might be possible with dd
but haven't figured it out yet :(
更新的 - 我想通了如何使用DD编辑文件的地方。此外的grep
,头
和剪切
是必要的。如果这些都不可用,则它们大概可以合作周围的大部分
Update - I figured out how to edit the file in place with dd. Also grep
, head
and cut
are needed. If these are not available then they can probably be worked around for the most part:
#!/bin/bash
# get the line number to remove
rline=$(grep -n "$1" "$2" | head -n1 | cut -d: -f1)
# number of bytes before the line to be removed
hbytes=$(head -n$((rline-1)) "$2" | wc -c)
# number of bytes to remove
rbytes=$(grep "$1" "$2" | wc -c)
# original file size
fsize=$(cat "$2" | wc -c)
# dd will start reading the file after the line to be removed
ddskip=$((hbytes + rbytes))
# dd will start writing at the beginning of the line to be removed
ddseek=$hbytes
# dd will move this many bytes
ddcount=$((fsize - hbytes - rbytes))
# the expected new file size
newsize=$((fsize - rbytes))
# move the bytes with dd. strace confirms the file is edited in place
dd bs=1 if="$2" skip=$ddskip seek=$ddseek conv=notrunc count=$ddcount of="$2"
# truncate the remainder bytes of the end of the file
dd bs=1 if="$2" skip=$newsize seek=$newsize count=0 of="$2"
运行它正是如此:
Run it thusly:
$ cat > file.txt
line 1
line two
line 3
$ ./grepremove "tw" file.txt
7+0 records in
7+0 records out
0+0 records in
0+0 records out
$ cat file.txt
line 1
line 3
$
我只想说, DD
为非常危险工具。您可以轻松地无意中覆盖文件或整个磁盘。要非常小心!
Suffice to say that dd
is a very dangerous tool. You can easily unintentionally overwrite files or entire disks. Be very careful!
这篇关于卸下文件中的特定行但不使用awk或者sed的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!