lire une list de lignes d'une sortie d'écriture de file vers un utilitaire

J'ai un file avec une list de lignes que je veux lire à partir d'un autre file. Je veux sortir ces lignes à un utilitaire ( grep ) qui me laisse lire toute la ligne et en tirer des informations. Le file avec les lignes ressemble à ceci:

 cat input.txt 2088 2089 2095 2096 

Pour une raison quelconque, je suis coincé là-dessus. Je sais que sed peut prendre un numéro de ligne spécifique comme argument, mais je n'arrive pas à comprendre comment l'intégrer dans une variable pour l'alimenter.

Si je comprends bien votre problème, quelque chose comme ça devrait fonctionner:

 for i in $(cat numbers.txt); do cat lines.txt|tail -n +$i|head -n 1; done 

Pour chacun des numéros du file "numbers.txt", il extrait la ligne correspondante de l'autre file et l'imprime.

La même chose avec sed et xargs ressemble à ceci:

 xargs -i sed "{}q;d" lines.txt <numbers.txt 

En supposant que l'interprétation de michas est correcte, voici une solution 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 

En Perl:

 perl -E ' while(<>){ chomp; if($file2) { say if exists $lines{$.} } else { $lines{$_}++ } } continue { if (eof){$.=0; $file2++} }'\ file_with_line_numbers other_file 
 awk 'NR==FNR{linesToPrint[$0];next} FNR in linesToPrint' line-numbers.txt file.txt 

Combine sed avec xargs et printf :

 sed -n $(xargs printf "%sp;" < input.txt) data 

-n indique à sed ne pas imprimer de lignes sauf si vous le dites explicitement. xargs exécute une command avec les lignes de l'input standard comme arguments. printf mettra en forme chaque argument comme décrit. Le $(...) ci-dessus s'étend à (pour votre file d'exemple):

 2088p;2089p;2095p;2096p; 

qui est une séquence de commands sed lui disant d'imprimer les lignes 2088, 2089, 2095 et 2096.

De cette façon, vous lisez chaque file une fois, plutôt que plusieurs fois pour xargs -i sed "{}q" ou xargs -i sed "{}q" piped head and tail .

Une autre solution perl :

 $ perl -MList::Util=any -nle ' BEGIN { open $fh, "<", "input.txt"; @lines = <$fh>; close $fh; } print if any { $_ == $. } @lines; ' file 
 sed '/[^0-9]/d;s/.$/&p/' <input.txt | sed -nf - file 

C'est deux sed s qui travaillent set. Le premier fait une petite tentative pour s'assurer qu'il ne modifie que les lignes appropriées en refusant d'imprimer toute ligne contenant un seul caractère non numérique et en éditant uniquement les lignes contenant au less un caractère. Fondamentalement, son travail, cependant, est juste de transformer votre list de numéros de ligne en:

 2088p 2089p 2095p 2096p 

Le second lit son script de command à partir de l'input standard et n'imprime pas les lignes par défaut, de sorte que toutes les lignes éditées par sed deviennent des lists de commands pour sed le second. Il exécute ces commands dans le file .

Apparemment, une technique similaire a déjà été recommandée, mais il existe une différence fondamentale entre les arguments d'invocation d'un process et les inputs. Il existe des limites distinctes sur les lists d'arguments comme:

 some_process $(seq a billion) 

Ce genre de chose est vouée à l'échec, mais, tant que le process sait comment le gérer, son apport est théoriquement illimité. Dans ce cas, sed lit un file – le |pipe – en input et le traite comme un script sed , ce qui est bien différent de lui donner une string de même longueur sur sa command line lors de l'invocation.