簡體   English   中英

如何使用 sed 刪除文件的最后 n 行

[英]How to use sed to remove the last n lines of a file

我想從文件末尾刪除一些n行。 這可以使用 sed 來完成嗎?

例如,要刪除從 2 到 4 的行,我可以使用

$ sed '2,4d' file

但我不知道行號。 我可以使用刪除最后一行

$sed $d file

但我想知道從末尾刪除n行的方法。 請讓我知道如何使用 sed 或其他方法來做到這一點。

我不知道sed ,但可以用head完成:

head -n -2 myfile.txt

如果硬編碼 n 是一個選項,您可以使用順序調用 sed。 例如,要刪除最后三行,將最后一行刪除三次:

sed '$d' file | sed '$d' | sed '$d'

sed one-liners

# delete the last 10 lines of a file
sed -e :a -e '$d;N;2,10ba' -e 'P;D'   # method 1
sed -n -e :a -e '1,10!{P;N;D;};N;ba'  # method 2

似乎是你正在尋找的東西。

一個有趣且簡單的sedtac解決方案:

n=4
tac file.txt | sed "1,$n{d}" | tac

筆記

  • shell 需要雙引號"來評估sed命令中的$n變量。在單引號中,不會執行插值。
  • taccat反轉的cat ,參見man 1 tac
  • sed中的{}用於分隔$nd (如果沒有,shell 會嘗試插入不存在的$nd變量)

使用sed ,但讓 shell 進行數學運算,目標是通過給出范圍(刪除最后 23 行)來使用d命令:

sed -i "$(($(wc -l < file)-22)),\$d" file

要從內到外刪除最后 3 行:

$(wc -l < file)

給出文件的行數:比如2196

我們要刪除最后 23 行,因此對於左側或范圍:

$((2196-22))

給出: 2174因此,shell 解釋后的原始 sed 是:

sed -i '2174,$d' file

使用-i進行就地編輯,文件現在是2173行!

如果要將其保存到新文件中,代碼為:

sed -i '2174,$d' file > outputfile

你可以使用head

采用

$ head --lines=-N file > new_file

其中 N 是要從文件中刪除的行數。

原始文件的內容減去最后 N 行現在在new_file 中

為了完整起見,我想添加我的解決方案。 我最終用標准ed做到了這一點:

ed -s sometextfile <<< $'-2,$d\nwq'

這將使用就地編輯刪除最后 2 行(盡管它確實使用了/tmp的臨時文件!!)

為了真正就地截斷非常大的文件,我們有truncate命令。 它不知道行,但tail + wc可以將行轉換為字節:

file=bigone.log
lines=3
truncate -s -$(tail -$lines $file | wc -c) $file

如果同時寫入文件,則存在明顯的競爭條件。 在這種情況下,使用head可能更好 - 它從文件的開頭(注意磁盤 IO)開始計算字節數,因此我們將始終在行邊界上截斷(如果文件被主動寫入,可能比預期的行多):

truncate -s $(head -n -$lines $file | wc -c) $file

如果您嘗試使用密碼代替用戶名嘗試登錄失敗,那么方便的單行:

truncate -s $(head -n -5 /var/log/secure | wc -c) /var/log/secure

這可能對你有用(GNU sed):

sed ':a;$!N;1,4ba;P;$d;D' file

以上大部分答案似乎都需要 GNU 命令/擴展:

    $ head -n -2 myfile.txt
    -2: Badly formed number

對於稍微更便攜的解決方案:

     perl -ne 'push(@fifo,$_);print shift(@fifo) if @fifo > 10;'

要么

     perl -ne 'push(@buf,$_);END{print @buf[0 ... $#buf-10]}'

要么

     awk '{buf[NR-1]=$0;}END{ for ( i=0; i < (NR-10); i++){ print buf[i];} }'

其中“10”是“n”。

通過這里的答案,您已經了解到 sed 不是此應用程序的最佳工具。

但是我確實認為有一種方法可以使用 sed 來做到這一點; 這個想法是附加 N 行來保存空間,直到您能夠在不點擊 EOF 的情況下閱讀。 當遇到 EOF 時,打印保留空間的內容並退出。

sed -e '$!{N;N;N;N;N;N;H;}' -e x

上面的 sed 命令將省略最后 5 行。

它可以通過 3 個步驟完成:

a) 計算要編輯的文件中的行數:

 n=`cat myfile |wc -l`

b) 從該數字中減去要刪除的行數:

 x=$((n-3))

c) 告訴 sed 從該行號 ( $x ) 刪除到末尾:

 sed "$x,\$d" myfile

您可以使用wc -l <file>獲取總行數並使用

head -n <total lines - lines to remove> <file>

嘗試以下命令:

n = line number
tail -r file_name | sed '1,nd' | tail -r

這將從file刪除最后 3 行:

for i in $(seq 1 3); do sed -i '$d' file; done;

我更喜歡這個解決方案;

head -$(gcalctool -s $(cat file | wc -l)-N) file

其中N是要刪除的行數。

刪除最后 4 行:

$ nl -b a file | sort -k1,1nr | sed '1, 4 d' | sort -k1,1n | sed 's/^ *[0-9]*\t//'   
sed -n ':pre
1,4 {N;b pre
    }
:cycle
$!{P;N;D;b cycle
  }' YourFile

posix版本

我想出了這個,其中 n 是您要刪除的行數:

count=`wc -l file`
lines=`expr "$count" - n`
head -n "$lines" file > temp.txt
mv temp.txt file
rm -f temp.txt

這有點迂回,但我認為它很容易遵循。

  1. 計算主文件中的行數
  2. 從計數中減去要刪除的行數
  3. 打印出要保留並存儲在臨時文件中的行數
  4. 用臨時文件替換主文件
  5. 刪除臨時文件

對於刪除文件的最后 N 行,您可以使用相同的概念

$ sed '2,4d' file

您可以使用帶有 tail 命令的組合來反轉文件:如果 N 為 5

$ tail -r file | sed '1,5d' file | tail -r > file

這種方式也可以在head -n -5 file命令不運行的地方運行(就像在 mac 上一樣!)。

在 docker 中,這對我有用:

head --lines=-N file_path >> file_path
#!/bin/sh

echo 'Enter the file name : '
read filename

echo 'Enter the number of lines from the end that needs to be deleted :'
read n

#Subtracting from the line number to get the nth line
m=`expr $n - 1`

# Calculate length of the file
len=`cat $filename|wc -l`

#Calculate the lines that must remain
lennew=`expr $len - $m`

sed "$lennew,$ d" $filename

類似於https://stackoverflow.com/a/24298204/1221137的解決方案,但在適當的位置進行了編輯並且沒有硬編碼行數:

n=4
seq $n | xargs -i sed -i -e '$d' my_file

假設您有幾行:

    $ cat <<EOF > 20lines.txt
> 1
> 2
> 3
[snip]
> 18
> 19
> 20
> EOF

然后你可以抓住:

# leave last 15 out
$ head -n5 20lines.txt
1
2
3
4
5

# skip first 14
$ tail -n +15 20lines.txt
15
16
17
18
19
20

使用ex / vi的 POSIX 兼容解決方案,與上述@Michel 的解決方案類似。 @Michel 的ed示例使用“非 POSIX”Here-Strings。 增加$-1以將n行刪除到 EOF ($),或者只輸入您想要 (d) 刪除的行。 您可以使用ex來計算行號或執行任何其他 Unix 的事情。

給定文件:

cat > sometextfile <<EOF
one
two
three
four
five
EOF

執行:

ex -s sometextfile <<'EOF'
$-1,$d
%p
wq!
EOF

回報:

one
two
three

這使用了 POSIX Here-Docs,因此非常容易修改 - 特別是使用set -o vi和 POSIX /bin/sh 在這個問題上,“vim”的“前性格”應該沒問題,但是 YMMV。

這將刪除最后 12 行

sed -n -e :a -e '1,10!{P;N;D;};N;ba'

暫無
暫無

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

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