我想从文件中删除一个或多个特定的行号。我怎么用sed做到这一点?
答案 0 :(得分:330)
如果要删除第5行到第10行和第12行:
sed -e '5,10d;12d' file
这会将结果打印到屏幕上。如果要将结果保存到同一文件:
sed -i.bak -e '5,10d;12d' file
这会将文件备份到file.bak
,并删除给定的行。
注意:行号从1开始。文件的第一行是1,而不是0。
答案 1 :(得分:35)
您可以删除特定的单行及其行号 sed -i'33d'文件
这将删除33行号上的行并保存更新的文件。
答案 2 :(得分:25)
和awk以及
awk 'NR!~/^(5|10|25)$/' file
答案 3 :(得分:16)
$ cat foo
1
2
3
4
5
$ sed -e '2d;4d' foo
1
3
5
$
答案 4 :(得分:5)
这通常是反模式的症状。产生行号的工具很可能被替换为立即删除行的工具。例如;
package sample;
/**
* Created by Angel on 7/26/16.
*/
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
public class Game {
// Inventory is a class that i made,
// but im sure it has nothing to do with my problem
private Inventory inv = new Inventory();
private String levels;
private Scene scene;
private Label topText;
private Button btn1;
private Button btn2;
private Button btn3;
private boolean gameOn;
public void gameStart(){
// Setting the GUI
// Setting up the window
VBox window = new VBox(210);
// setting up the top text holder.
HBox textHolder = new HBox();
textHolder.setAlignment(Pos.CENTER);
// setting up the label
topText = new Label();
topText.setText("You in a dark room, what do you do?");
// setting up the button holder
HBox buttonHolder = new HBox(50);
buttonHolder.setAlignment(Pos.CENTER);
// setting up the buttons
btn1 = new Button();
btn1.setPrefWidth(260);
btn1.setPrefHeight(30);
btn1.getStyleClass().add("gameButtons");
btn1.setText("1");
btn2 = new Button();
btn2.setPrefWidth(260);
btn2.setPrefHeight(30);
btn2.getStyleClass().add("gameButtons");
btn2.setText("2");
btn3 = new Button();
btn3.setPrefWidth(260);
btn3.setPrefHeight(30);
btn3.getStyleClass().add("gameButtons");
btn3.setText("3");
// finalizing the gui, by putting it all together
textHolder.getChildren().add(topText);
buttonHolder.getChildren().addAll(btn1, btn2, btn3);
window.getChildren().addAll(textHolder, buttonHolder);
// setting up the scene
scene = new Scene(window, 800, 600);
//adding the css script
// adding css script
scene.getStylesheets().add(this.getClass().getResource("game.css").toExternalForm());
// the game loop.
levels = "Storyline";
gameOn = true;
while(gameOn) {
switch (levels) {
case "Storyline":
btn1.setText("search around");
btn2.setText("turn the light on");
btn3.setText("stand in fear");
btn2.setOnAction(e -> levels = "level1");
break;
case "level1":
topText.setText("You turned the light on");
break;
}
}
}
public Scene getScene(){
return scene;
}
}
(其中grep -nh error logfile | cut -d: -f1 | deletelines logfile
是您想象的实用程序)与
deletelines
话虽如此,如果您确实需要执行此任务,可以从行号文件生成简单的grep -v error logfile
脚本。幽默地(但也许有点令人困惑)你可以用sed
来做到这一点。
sed
这接受一个行号文件,每行一个,并在标准输出上生成相同的行号,每行后附加sed 's%$%d%' linenumbers
。这是一个有效的d
脚本,我们可以将其保存到文件中,或者(在某些平台上)管道到另一个sed
实例:
sed
在某些平台上,sed 's%$%d%' linenumbers | sed -f - logfile
不理解选项参数sed -f
表示标准输入,因此您必须将脚本重定向到临时文件,并在完成后清理它,或者如果你的操作系统(或shell)有这个,可以用-
或/dev/stdin
替换单独的短划线。
与往常一样,您可以在/proc/$pid/fd/1
选项之前添加-i
,以便-f
编辑目标文件,而不是在标准输出上生成结果。在* BSDish平台(包括OSX)上,您还需要向sed
提供显式参数;一个常见的习语就是提供一个空洞的论点; -i
。
答案 5 :(得分:2)
我想用awk提出一个概括。
当文件由固定大小的块构成时 并且每个块重复要删除的行, awk可以这样的方式正常工作
awk '{nl=((NR-1)%2000)+1; if ( (nl<714) || ((nl>1025)&&(nl<1029)) ) print $0}'
OriginFile.dat > MyOutputCuttedFile.dat
在这个例子中,块的大小是2000,我想打印[1..713]和[1026..1029]行。
NR
是awk用来存储当前行号的变量。%
给出两个整数除法的余数(或模数); nl=((NR-1)%BLOCKSIZE)+1
这里我们在变量 nl 中写入当前块内的行号。 (见下文)||
和&&
是逻辑运算符 OR 和 AND 。 print $0
写完整行Why ((NR-1)%BLOCKSIZE)+1:
(NR-1) We need a shift of one because 1%3=1, 2%3=2, but 3%3=0.
+1 We add again 1 because we want to restore the desired order.
+-----+------+----------+------------+
| NR | NR%3 | (NR-1)%3 | (NR-1)%3+1 |
+-----+------+----------+------------+
| 1 | 1 | 0 | 1 |
| 2 | 2 | 1 | 2 |
| 3 | 0 | 2 | 3 |
| 4 | 1 | 0 | 1 |
+-----+------+----------+------------+
答案 6 :(得分:0)
sed
中的第一行sed -i '1d' file
正如 Brian 所说的 here,使用了 <address><command>
,<address>
是 <1>
和 <command>
<d>
。