A
テキストファイルから削除したい行番号を含むテキストファイルがありますB
。たとえば、ファイルにはA.txt
次の行が含まれています。
1
4
5
ファイルB.txt
には次の行が含まれています。
A
B
C
D
E
生成されたファイルは次のようになります。
B
C
もちろん手動で行うこともできますが、
sed '1d;4d;5d' B.txt
しかし、行番号を手動で指定せずにこれを行う方法を知りたいです。
答え1
awk
以下も使用できます。
awk 'NR==FNR { nums[$0]; next } !(FNR in nums)' linenum infile
特別な場合に「linenum」ファイルが空の場合、awkはそれをスキップするため、「infile」行全体を印刷しません。この問題を解決するには、次のコマンドを使用します。
awk 'NR==FNR && FILENAME==ARGV[1]{ nums[$0]; next } !(FNR in nums)' linenum infile
またはより良い(ありがとうスティーブン・チャジェラス):
awk '!firstfile_proceed { nums[$0]; next }
!(FNR in nums)' linenum firstfile_proceed=1 infile
答え2
sed プログラムを作成するには、sed を使用します。
sed "$(sed 's/$/d/' A.txt)" B.txt > C.txt
「プログラム」はさらに複雑になる可能性があります。たとえば、行が数値であることを確認したり、コメント構文を作成して削除したりできます。
答え3
別のアプローチは、基本的なシェルコマンドを組み合わせることです。
join -v1 <(nl file) line_numbers | cut -d' ' -f2-
または:
nl file | join -v1 - line_numbers | cut -d' ' -f2-
nl
ファイルの行番号を付けてから、join -v1
2 番目のファイルに一致しない行だけを保持し、最後にcut
行番号を保持するために使用します。ファイルをline_numbers
並べ替える必要があります。
答え4
for i in `cat fileA`; do sed -n ''$i'p' fileB; done >>content.txt
for i in `cat content.txt`; do sed -i '/^'$i'$/d' fileB;done
output
B
C