卸下文件中的特定行但不使用awk或者sed [英] Remove a specific line from a file WITHOUT using sed or awk

查看:189
本文介绍了卸下文件中的特定行但不使用awk或者sed的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要从使用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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆