別のファイルから読み取りたい行のリストを含むファイルがあります。これらの行をユーティリティ(grep
)に出力して、行全体を読み取り、そこから情報を取得できるようにします。行のあるファイルは次のようになります。
cat input.txt
2088
2089
2095
2096
どういうわけか私はこれで立ち往生しています。 sed
が特定の行番号を引数として取ることができることは知っていますが、これを変数に入れてフィードする方法がわかりません。
awk 'NR==FNR{linesToPrint[$0];next}
FNR in linesToPrint' line-numbers.txt file.txt
私があなたの問題を正しく理解していれば、このようなことがうまくいくはずです:
for i in $(cat numbers.txt); do cat lines.txt|tail -n +$i|head -n 1; done
ファイル「numbers.txt」内の番号ごとに、他のファイルの対応する行を抽出して出力します。
sed
とxargs
の同じものは次のようになります。
xargs -i sed "{}q;d" lines.txt <numbers.txt
michasの解釈 が正しいと仮定すると、ここにawk
ソリューションがあります。
awk 'FNR==NR{a[i++]=$0} # Process the first file
FNR!=NR{ # Process the second file
for (i in a){
if(FNR==a[i]){
print $0
}
}
}' file_with_line_numbers other_file
Perlの場合:
Perl -E '
while(<>){
chomp;
if($file2) { say if exists $lines{$.} }
else { $lines{$_}++ }
} continue { if (eof){$.=0; $file2++} }'\
file_with_line_numbers other_file
sed '/[^0-9]/d;s/.$/&p/' <input.txt |
sed -nf - file
これは、2つのsed
が連携して機能することです。 1つ目は、数字以外の1文字を含む行の印刷を拒否し、少なくとも1文字を含む行のみを編集することにより、適切な行のみを編集するように少し試みます。ただし、基本的にその仕事は、行番号のリストを次のように変換することです。
2088p
2089p
2095p
2096p
2番目は標準入力からコマンドスクリプトを読み取り、デフォルトでは行を出力しないため、最初のsed
によって編集されたすべての行は、2番目のsed
のコマンドのリストになります。これらのコマンドはfile
で実行されます。
どうやら同様の手法がすでに推奨されているようですが、プロセスの呼び出し引数と入力の間には根本的な違いがあります。次のような引数リストには明確な制限があります。
some_process $(seq a billion)
そのようなことは必ず失敗しますが、プロセスがそれを処理する方法を知っている限り、その入力は理論的には無制限です。したがって、この場合、sed
はファイルを読み取ります-|pipe
-入力として、sed
スクリプトのように処理します。これは、呼び出し時にコマンドラインで同じ長さの文字列を渡すのとは大きく異なります。
sed
を xargs
および printf
と組み合わせる:
_sed -n $(xargs printf "%sp;" < input.txt) data
_
_-n
_は、明示的に指示しない限り、行を印刷しないようにsed
に指示します。 xargs
は、標準入力からの行を引数としてコマンドを実行します。 printf
は、説明されているように各引数をフォーマットします。上記の$(...)
は(サンプルファイルの場合)次のように展開されます。
_2088p;2089p;2095p;2096p;
_
これは、行2088、2089、2095、および2096を印刷するように指示する一連のsed
コマンドです。
このようにして、_xargs -i sed "{}q"
_またはパイプされたhead
とtail
に対して何度もではなく、各ファイルを1回読み取ります。
別のPerl
ソリューション:
$ Perl -MList::Util=any -nle '
BEGIN {
open $fh, "<", "input.txt";
@lines = <$fh>;
close $fh;
}
print if any { $_ == $. } @lines;
' file