기록에서 고유한 단일 명령을 추출합니다.

기록에서 고유한 단일 명령을 추출합니다.

명령 기록( 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에 알립니다. 그런 다음 첫 번째 필드가 다음인지 확인하세요. 숫자 뒤에 점이 있고, 그렇다면 줄의 시작 부분에 있으므로 두 번째 필드가 인쇄되고, 그렇지 않으면 첫 번째 필드가 인쇄됩니다.

관련 정보