ファイルの最後のn行を編集するにはどうすればよいですか?


10

ファイルの最後のn行を編集できるコマンドはありますか?私はいくつかのファイルを持っていますが、そのすべてに異なる行数が含まれています。しかし、各ファイルの最後のn行を変更したいと思います。目標は、最後のn行でコンマをセミコロンに置き換えることです。しかし、最後のn行のみです。

行を削除したくありません。各ファイルの最後のn行のすべてのコンマをセミコロンに置き換えたいだけです。

sedコマンドを使用して、最後の行をこのコマンドで置き換えることができます。ここで説明するように: ファイルの最後の行のテキストを削除するにはどうすればよいですか?

しかし、これにより、最後のn行ではなく、最後の行のみを変更できます。


1
単にスタートラインsed '24,$s/,/:/g' filename がどこに24あるかを使用する`
Valentin Bajrami

回答:


13

最後のn行のコンマをセミコロンに置き換えるには、次のようにしますed

n=3
ed -s input <<< '$-'$((n-1))$',$s/,/;/g\nwq'

それを分ける:

  • ed -s =静かにedを実行します(最後に書き込まれたバイトを報告しないでください)
  • '$-'=ファイルの最後から($)マイナス...
  • $((n-1)) = n-1行...
  • $' ... '=シェルからコマンドを保護するために残りのコマンドを引用する)
  • ,$s/,/;/g= ...ファイルの終わり(,$)まで、すべてのコンマを検索してセミコロンで置き換えます。
  • \nwq =前のコマンドを終了し、保存して終了

最後のn行のコンマをセミコロンに置き換えるには、次のようにしますsed

n=3
sed -i "$(( $(wc -l < input) - n + 1)),\$s/,/;/g" input

それを分解する:

  • -i =「インプレース」でファイルを編集
  • $(( ... )) =いくつかの計算を行います:
  • $( wc -l < input) =ファイルの行数を取得する
  • -n + 1 = n-1行後戻り
  • ,\$ = n-1行からファイルの終わりまで:
  • s/,/;/g =カンマをセミコロンに置き換えます。

置き換えることができますwc -l < inputwc -l input。数ナノ秒高速になるはずです:)
gardenhead '21 / 06/17

1
ただしwc -l input、ファイル名も出力されます。行数だけが必要です
ジェフシャラー

edの最初のアドバイスは、細かく簡単です。
sku2003 2017

実際、私はまったく別の側面から助けを得ました。これにより、奇妙なコードができました。これはトリックを実行しますが、長くて奇妙です。これは、解決策をまとめるときに最終的に発生する可能性がある奇妙なことの一部だと思います。とにかく、あなたのものはきれいで、私のものより短くて複雑ではありません:ここのコードも機能しました:
sku2003 '22

cat input.file | sed 's /、/、\ n / g' | sed -n '1!G; h; $ p' | awk -vn = 2 'NR <= n {gsub( "、"、 ";"、$ 0)} {print}' | sed -n '1!G; h; $ p' | sed '/ ^ \ s * $ / d'> output.file
sku2003

6

file.txtの最後の50行で、tacsedを使用してすべてのコンマをセミコロンに置き換えるソリューション:

tac file.txt | sed '1,50s/,/;/g' | tac

5

GNU headとBourneのようなシェルの場合:

n=20
{ head -n -"$n"; tr , ';'; } < file 1<> file

ファイル自体を上書きしています。これは、バイトツーバイト音訳のために、ここでOKですが、変更は、ファイルのサイズを変更することを意味している場合は限らない(その場合には、あなたが交換したいと思うだろう1<> file> other-file && mv other-file fileインスタンスのため)。


1
1<>これは私がよく知らないのドキュメントです。また、spongeからmoreutilsあなたの入力を上書きするパイプラインのための優れたツールです。
マイル

1

7次のシーケンスの最後の行をシェルスクリプトとGNUの実装に置き換えたいとしましょうsed

$ seq 20
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

ステップ1:次のようなシーケンスの最後の行番号を取得します。これそれを見てください:

$ lastLine=`seq 20|sed -n '$='`

$ echo $lastLine 
20

ステップ2:編集する行数(シーケンスの最後)を設定します。

$ numberOfLines=7

$ echo $numberOfLines 
7

手順3:次のように、以前の変数に基づいてスタートラインを計算します。これを見てください:

$ startLine=`expr $lastLine - $numberOfLines + 1`

$ echo $startLine 
14

ステップ4:これで、シーケンスの最後の7行を次のような別のものに置き換えることができます。これを見てください:

$ seq 20|sed -e "$startLine,+$numberOfLines{s/[12]/WoW/}"
1
2
3
4
5
6
7
8
9
10
11
12
13
WoW4
WoW5
WoW6
WoW7
WoW8
WoW9
WoW0

ステップ4では、sedのmanページのセクション4.4を使用しています。

'ADDR1,+N'
     Matches ADDR1 and the N lines following ADDR1.

ステップ4でも、ここで述べたように二重引用符を使用ています


さて、次のような五答えを使えば、4つのステップは不要です。

$ seq 20 |tac|sed -e '1,7{s/[12]/WoW/}'|tac
1
2
3
4
5
6
7
8
9
10
11
12
13
WoW4
WoW5
WoW6
WoW7
WoW8
WoW9
WoW0

0

tailsedへの使用とパイプ:

tail -n 20 file | sed 's/,/;/g'

これは、最後の20行のファイルで機能します。ファイルを直接使用できるようにしたい場合:

tail -n 20 file | sed -i 's/,/;/g'

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.