0

sedを使用してファイルの一部の行を削除するbashスクリプトを作成しようとしています。行番号は逆の順序で別のファイルに保存されます。私がやろうとしているコマンドは次のとおりです。

sed -e '{lineNumber}d' ./file.txt

これは私が今まで持っているものですが、機能していません

while read -r line 
do 
   sed -e "/${line}d" ./file.txt
done < ./lineNum.txt

次のエラーが発生します:
sed:-e式#1、文字4:未終了のアドレス正規表現

4

4 に答える 4

3

実際にあなたが間違ったことはこれです

sed -e "/${line}d" ./file.txt

ほら、sedこの構文があります

sed -e "/REGEX/d" ./file.txt

パターンに一致するものを含むすべての行を削除しREGEXます。あなたは最初のものを持っているので/、sedはあなたが正規表現マッチングを使おうとしていると考えているので、それは言っていunterminated address regexます。

必要な最小限の修正は、問題のあるバックスラッシュを削除することです。

sed -e "${line}d" ./file.txt

余談ですが、OPが要求したようなソリューションではありませんsedが、OPが望むことをより効率的に実行します。

awk 'NR==FNR {arr[$0]++; next} {if (!arr[FNR]) print }' linenum.txt file.txt
于 2012-10-20T02:05:15.450 に答える
2

削除する行が途方もなく多くなく、バージョンがひどく制限されているシステムで作業していない限りsed(かつて、sedHP-UXでは約100コマンドに制限されていました)、次を使用できます。

sed 's/$/d/' linenum.txt | sed -f - file.txt

これは、最初sedの行番号を削除コマンドに変換し(問題の一部は不要なスラッシュであることに注意してください)、2番目のコマンドにsed標準入力(-f -)からスクリプトを読み取ってに適用するように指示しますfile.txt

上記はGNUで動作しますsed; sedMac OS X 10.7.5のBSDでは動作しませんでした( sed: -: No such file or directory)。システムで使用する前にテストしてください。

もちろん、bashbash4.2では動作するが3.2では動作しない)の十分に新しいバージョンがある場合は、「プロセス置換」を使用して次の制限を回避できますsed

 sed -f <(sed 's/$/d/' linenum.txt) file.txt

それでも機能しない場合は、最初のsedコマンドの出力をファイルに書き込んでから、その(一時)ファイルをsedスクリプトの名前として使用できます。ですから、それを行う方法はたくさんあります。ただし、3つを超えるプロセス(2回の実行sedと1回の実行rm)は贅沢です。一度だけ行う必要がある場合はおそらく問題ではありませんが、1分間に何度も行う必要がある場合は問題になる可能性があります。

于 2012-10-20T04:27:08.623 に答える
1

sedループを使用せずに、を使用して直接変更を加えることができます。

sed 's/.*/&d/' lineNum.txt | sed -i -f - file.txt
于 2012-10-20T01:02:22.413 に答える
1
while read -r line; do sed -i "${line} d" ./file.txt; done < ./linenum.txt

これは機能します(あなたの問題は-eを使用することだったと思います)。しかし、それは効率的ではありません。1行に1回ファイルの読み取りと書き込みを行わないように、sedに一度に複数の行を渡す方がよい場合があります。たとえば、linenum.txtを「6d; 2d;1d;」のようなものに変換できます。次に、それをsedに渡して1回のスクープ処理を行います。

于 2012-10-20T00:54:35.197 に答える