
いいですね。迅速な方法を探しています。テキストデータファイルに変更する必要がある行番号のリストがあります。ラインの16ビットモードは何でも構いませんが、XXXXXXXXXXXXXXXX
ライン番号に応じて読み取りのみを可能にするように変更する必要があります。もう一度変更する必要がある行番号の長いリストがあります。変更する線には明確なパターンはありません。 (データスキーマを作成していませんが、すべてのデータを読み取るためにどの行を変更する必要があるかを知っています。
まだ明確でない場合は、別の方法で説明します。
ファイルの26115、32198、37256、40001、40023行を読み取るように変更しますXXXXXXXXXXXXXXX
。 190万行のファイルで変更する行が100,000を超えています。
答え1
@Gillesの答えへの拡張としてファイルに変更する必要がある行番号があると言ったので(並べ替えられ、呼び出されたとしますlinums
)
awk '
BEGIN { getline NEXT < "linums" }
NR == NEXT { $0 = "XXXXXXXXXXXXXXX"; getline NEXT < "linums" }
1
'
これは、数千の行番号を手動で入力することなく、数千の行を変更するのに適しています。
または、わずかに変更すると、変更したい行番号またはファイルを取得できますstdin
。これに対してスクリプトを作成します。 (と呼びますredact.awk
)
#!/usr/bin/awk -f
BEGIN {
LINUMS = ARGV[1]
ARGV[1] = ARGV[2]
--ARGC
getline NEXT < LINUMS
}
NR == NEXT {
$0 = "XXXXXXXXXXXXXXX"
getline NEXT < LINUMS
}
1
その後、次のいずれかを使用できます。
$ ./redact.awk linums file-to-be-changed
$ ./redact.awk - file-to-be-changed
$ ./redact.awk linums -
$ ./redact.awk linums
(後者の2つは同じです)
答え2
sedとawkの両方がこれをうまく実行できます。
sed '
26115 s/.*/XXXXXXXXXXXXXXX/
32198 s/.*/XXXXXXXXXXXXXXX/
37256 s/.*/XXXXXXXXXXXXXXX/
40001 s/.*/XXXXXXXXXXXXXXX/
40023 s/.*/XXXXXXXXXXXXXXX/
'
awk '
NR==26115 || NR==32198 || NR==37256 || NR==40001 || NR==40023 {$0 = "XXXXXXXXXXXXXXX"}
1
'
1
(以前のコードが可能なすべての変換を実行した後、すべての行が個別に印刷されます。)
答え3
sed -e '1{x;s/^/XXXXXXXXXXXXXXX/;x;}
26115bp
32198bp
37256bp
40001bp
40023bp
d
:p
g
' data_file
まず、予約済みスペースを必要なパターンで埋め、予約済みXXXXXXXXX
スペースを検索し、暗黙的に標準出力に送信するラベル:pにジャンプして、必要な行番号のみを呼び出します。一致しない行は削除されます(d
続行するにはに変更)。b
答え4
では、交換が静的で複数行を置き換えることが非常に簡単なので、作業を実行するための大規模なスクリプトを作成sed
できます。sed
行番号を1行に1つずつ別々のファイルに入れるとすると、次のように(GNU)スクリプトを生成linenos.txt
できます。sed
$ awk '{ printf("%dc XXXXXXXXXXXXXXX\n", $0) }' linenos.txt >script.sed
または
$ awk '{ print $0, "c XXXXXXXXXXXXXXX" }' linenos.txt >script.sed
次にファイルに適用します。
$ sed -f script.sed file >file.new
注:私は非常に大きなスクリプトを実行したことがないので、GNUがパフォーマンスの観点からスクリプトをどのようにsed
処理するのかわかりません。sed