コマンド履歴(history > histcopy.txt
)を含むhistcopy.txtというファイルを作成しました。次のように見えます。
1. l
2. ls
3. cat necopy.txt
4. netstat
5. cd | ls-l ; grep -i "3" histcopy.txt | echo
すべてのユニークなコマンドを印刷したいです。これまでに実行したコマンドは次のとおりです。
awk '{print $2}' histcopy.txt | sort|uniq`
結果は次のとおりです。
l
ls
cat
netstat
cd
しかし、最後の行(5. cd | ls-l ; grep -i "3" histcopy.txt | echo
)には無視して最初のコマンドだけを取るコマンドがたくさんありますcd
。現在のコマンドも抽出されるように、どのように書き換えることができますか?このようにして5行目から次も抽出されます。
ls-l
grep -i "3: histcopy.txt
echo
出力リストに別の項目として含めます。
答え1
$ cat histcopy.txt
1 l
2 ls
3 cat necopy.txt
4 netstat
5 cd | ls -l ; grep -i "3" histcopy.txt | echo
$ sed 's/^\s*\S*\s*//' histcopy.txt | tr ';|' '\n' | awk '!seen[$1]++{print $1}'
l
ls
cat
netstat
cd
grep
echo
sed 's/^\s*\S*\s*//'
history
出力からコマンドに関連する初期スペースと数字を削除します。tr ';|' '\n'
;
とを|
改行文字に置き換えます。これは現在の問題の説明では機能しますが、代替項目にコマンドなどがある場合は役に立ちません。awk '!seen[$1]++{print $1}'
固有コマンド
perl
同様のロジックを別々に実装
$ perl -lne 's/^\s*\S+//; (@a)= split/[;|]/; foreach (@a){($k) = /^\s*\K(\S+)/; print $k if !$seen{$k}++}' histcopy.txt
l
ls
cat
netstat
cd
grep
echo
答え2
続行するには、次の手順を実行しますawk
。
awk 'BEGIN {RS="\n|\\||;|\\$\\("}
$1 ~ /^[0-9]+\./ {print $2; next}
{print $1}' file | sort | uniq
説明する: レコード区切り文字が改行、"|"、";"または、「$(」である可能性があるため、パイプ、置換、またはリンクコマンドがレコードに分割される可能性があることをawkに通知します。次に、最初のフィールドが次のものであることを確認してください。最初のフィールドが印刷され、それ以外の場合は最初のフィールドが印刷されます。