簡體   English   中英

如何使用sed僅刪除文件中第一次出現的行

[英]How to remove only the first occurrence of a line in a file using sed

我有以下文件

titi
tata
toto
tata

如果我執行

sed -i "/tat/d" file.txt

它將刪除包含tat所有行。 該命令返回:

titi
toto

但是我想只刪除包含tat的文件中出現的第一行:

titi
toto
tata

我怎樣才能做到這一點?

您可以使用雙地址格式:

sed '0,/tat/{/tat/d;}' inputfile

這將刪除模式的第一次出現。

引自info sed

 A line number of `0' can be used in an address specification like
 `0,/REGEXP/' so that `sed' will try to match REGEXP in the first
 input line too.  In other words, `0,/REGEXP/' is similar to
 `1,/REGEXP/', except that if ADDR2 matches the very first line of
 input the `0,/REGEXP/' form will consider it to end the range,
 whereas the `1,/REGEXP/' form will match the beginning of its
 range and hence make the range span up to the _second_ occurrence
 of the regular expression.

如果你可以使用awk ,那么這就是:

$ awk '/tata/ && !f{f=1; next} 1' file
titi
toto
tata

要將結果保存在當前文件中,請執行

awk '...' file > tmp_file && mv tmp_file file

說明

每當tata第一次匹配時,讓我們激活一個標志並跳過該行。 從那一刻開始,不要跳過這些線。

  • /tata/匹配包含字符串tata
  • {f=1; next} {f=1; next}將標志f設置為1,然后跳過該行。
  • !f{}如果設置了標志f ,則跳過此塊。
  • 1 ,作為True值,執行默認的awk操作: {print $0}

Tom Fenech的另一種方法

awk '!/tata/ || f++' file

|| 代表OR,所以這個條件是真的,因此每當發生任何這些情況時都會打印該行:

  • tata沒有找到。
  • f++是真的。 這是一個棘手的部分:第一次f默認為0,所以第一個f++將返回False而不打印該行。 從那一刻起,它將從整數值開始增加,並且將為True。

以下是使用sed執行此操作的一種方法:

sed ':a;$!{N;ba};s/\ntat[^\n]*//' file
titi
toto
tata

這是一般的方法:

$ cat file
     1  titi
     2  tata
     3  toto
     4  tata
     5  foo
     6  tata
     7  bar
$
$ awk '/tat/{ if (++f == 1) next} 1' file
     1  titi
     3  toto
     4  tata
     5  foo
     6  tata
     7  bar
$
$ awk '/tat/{ if (++f == 2) next} 1' file
     1  titi
     2  tata
     3  toto
     5  foo
     6  tata
     7  bar
$
$ awk '/tat/{ if (++f ~ /^(1|2)$/) next} 1' file
     1  titi
     3  toto
     5  foo
     6  tata
     7  bar

請注意,使用上述方法,您可以跳過您喜歡的RE的任何事件(第1,第2,第1和第2,無論如何),並且您只指定RE一次(而不是為了某些替代解決方案而必須復制它) 。

清晰,簡單,明顯,易於維護,可擴展等....

這可能適合你(GNU sed):

sed '/pattern/{x;//!d;x}' file

正常打印除包含圖案的行以外的所有行。 否則,如果該行包含模式並且保持空間不存在(第一次出現),則刪除該行。

您可以使用grep找到第一個匹配的行號,並將其傳遞給sed進行刪除。

sed "$((grep -nm1 tat file.txt || echo 1000000000:) | cut -f 1 -d:) d" file.txt

grep -ncut結合查找要刪除的行號。 grep -m1確保最多找到一個行號。 echo在沒有匹配時處理大小寫,以便不返回空結果。 sed "[line number] d"刪除該行。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM