이 bash 스크립트가 있습니다.
#!/usr/bin/env bash
DOMAINS=( '.com' '.co' )
while read input; do
for (( i=0;i<${#DOMAINS[@]};i++)); do
MATCH=$(whois "$input${DOMAINS[$i]}" | grep -oPa '^.*\b(Creation Date)\b.*$')
if [ $? -eq 0 ]; then
echo -e "$input${DOMAINS[$i]}\tregistered\t"$(date +%y/%m/%d_%H:%M:%S)"\t$MATCH" | tr '\n' '\t' |& tee --append output/registered.txt
echo "" |& tee --append output/registered.txt
else
echo -e "$input${DOMAINS[$i]}\tavailable\t"$(date +%y/%m/%d_%H:%M:%S)"\t$MATCH" | tr '\n' '\t' |& tee --append output/available.txt
echo "" |& tee --append output/available.txt
fi
done
done < "$1"
input.txt는 다음과 같습니다.
domain1
domain2
domain3
콘솔로 되돌립니다.
$ ./script.sh input.txt
$ domain1.com registered Creation date: 15-jan-2015
$ domain1.co available Creation date: 15-jan-2015
$ domain2.com registered Creation date: 15-jan-2015
$ domain2.co registered Creation date: 15-jan-2015
$ domain3.com registered Creation date: 15-jan-2015
$ domain3.co registered Creation date: 15-jan-2015
input.txt에서 읽은 줄을 제거하려면 이 스크립트를 어떻게 수정해야 합니까?
당신의 도움을 주셔서 감사합니다!
편집하다:
Cas의 솔루션은 다음과 같습니다.
#!/bin/bash
DOMAINS='.com .co' # simple, space-separated list of domain suffixes
while read input; do
for d in $DOMAINS; do
MATCH=$(whois "$input$d" | grep -oPa '^.*\b(Creation Date)\b.*$')
if [ $? ] ; then regavail="registered" ; else regavail="available" ; fi
# what's the `tr` for below? is it really needed?
# Is $MATCH really going to have more then one line in it?
out=$(printf '%s\t%s' "$(date +%y/%m/%d_%H:%M:%S)" "$MATCH" | tr '\n' '\t')
printf '%s\t%s\t%s\n' "$input$d" "$regavail" "$out" |& tee --append "output/$regavail.txt"
seen+="$input\|"
done
done < "$1"
seen=$(printf '%s' "$seen" | sed -e 's/\\|$//')
sed -i -e "/^\($seen\)$/d" "$1"
이것은 훌륭하지만 스크립트가 완전히 완료된 후에만 이 줄을 제거합니다. CTRL+C를 사용하여 스크립트를 종료할 때 이 줄을 제거할 수 있는 방법이 있습니까?
CTRL+C를 "잡기"(여기서 사용하기에 좋은 용어인 경우)하고 스크립트가 input.txt의 마지막 줄에 도달하는 경우와 같은 신호를 보내려면 어떻게 해야 합니까? 처리된 행이 삭제됩니까, 아니면 처리되지 않은 행을 포함하여 전체 input.txt 파일이 삭제됩니까?
고쳐 쓰다:
input-cache.txt
실시간으로 파일을 생성하고 사용된 줄을 제거하는 버전은 다음과 같습니다 . input-cache.txt
존재하지 않는 경우 input.txt
그대로 두십시오. 따라서 처음 시작할 때 input.txt
이 파일의 모든 내용을 에 복사합니다 input-cache.txt
. 스크립트는 에서 읽지 input.txt
만 sed
명령은 실시간으로 미러에서 해당 줄을 계속 제거합니다 input-cache.txt
. 스크립트를 처음 시작하는 경우입니다. 하지만 CTRL+C를 사용하여 스크립트 실행을 중지하면 어떻게 될까요? 이 경우 의 모든 내용이 input.txt
다시 반전되어 input-cache.txt
에서와 마찬가지로 처리되지 않은 행만 남게 됩니다 input-cache.txt
. 한 가지 단점은 새 줄을 추가하면 input.txt
다음에 시작할 때 즉시 삭제된다는 것입니다. 또한 스크립트의 파일은 하드코드되어 있습니다. fire up 명령을 사용하여 지정한 입력 파일을 호출하는 방법을 모르겠습니다 ./script.sh files/input.txt
.
input.txt
스크립트를 다시 시작할 때 캐시 파일을 다시 작성하는 것보다 캐시 파일을 생성하는 더 좋은 방법이 있을 수 있습니다.
#!/bin/bash
# USAGE
# ./script.sh files/input.txt
cat files/input-cache.txt > files/input.txt
cat files/input.txt > files/input-cache.txt
DOMAINS='.com'
while read -r input; do
for d in $DOMAINS; do
MATCH=$(whois "$input$d" | grep -oPa '^.*\b(Creation Date)\b.*$')
if [ $? -eq 0 ]; then
echo "" |& tee --append files/registered.txt
echo -e "$input$d\tregistered\t"$(date +%y/%m/%d_%H:%M:%S)"\t$MATCH" | tr '\n' '\t' |& tee --append files/registered.txt
else
echo "" |& tee --append files/available.txt
echo -e "$input$d\tavailable\t"$(date +%y/%m/%d_%H:%M:%S)"\t$MATCH" | tr '\n' '\t' |& tee --append files/available.txt
fi
done
sed -i "/$input/d" files/input-cache.txt
done < "$1"
답변1
fi
와 첫 번째 줄 사이에 다음 줄을 추가합니다 done
.
seen+="$input\|"
그런 다음 마지막 줄 뒤에 done
다음 줄을 추가합니다 .
seen=$(printf '%s' "$seen" | sed -e 's/\\|$//')
sed -i -e "/^\($seen\)$/d" "$1"
그러면 입력 파일("$1")에서 확인 및 처리된 모든 도메인을 포함하는 정규식을 작성한 다음 해당 파일에서 해당 도메인을 모두 제거합니다.
사용 중인 버전이 ( ) 옵션을 sed
지원하지 않는 경우 임시 파일을 대신 사용할 수 있습니다.-i
--in-place
tf=$(mktemp)
sed -e "/^\($seen\)$/d" "$1" > "$tf" && mv -f "$tf" "$1" || rm -f "$tf"
다음은 더 간단하고 읽기 쉽고 유지 관리가 쉬운 스크립트 버전입니다.
#!/bin/bash
DOMAINS='.com .co' # simple, space-separated list of domain suffixes
while read input; do
for d in $DOMAINS; do
MATCH=$(whois "$input$d" | grep -oPa '^.*\b(Creation Date)\b.*$')
if [ $? ] ; then regavail="registered" ; else regavail="available" ; fi
# what's the `tr` for below? is it really needed?
# Is $MATCH really going to have more then one line in it?
out=$(printf '%s\t%s' "$(date +%y/%m/%d_%H:%M:%S)" "$MATCH" | tr '\n' '\t')
printf '%s\t%s\t%s\n' "$input$d" "$regavail" "$out" |& tee --append "output/$regavail.txt"
seen+="$input\|"
done
done < "$1"
seen=$(printf '%s' "$seen" | sed -e 's/\\|$//')
sed -i -e "/^\($seen\)$/d" "$1"