while 루프 쉘 스크립트를 사용한 egrep

while 루프 쉘 스크립트를 사용한 egrep

디렉토리에 파일 목록이 있습니다 /tmp/drop. 내 질문의 기본 요소를 포함시켰습니다 test script zz.sh. 스크립트의 일부를 가져와 여기에 올렸습니다. 나열된 파일과 줄은 다음과 같습니다. while 루프에 제공될 때 file변수에 파일 이름만 할당하고 이 줄의 다양한 다른 문자열은 할당하지 않는 방법은 무엇입니까?

어떤 도움이라도 크게 감사할 것이며 다른 사람들에게도 도움이 될 수 있습니다.

machine001:/home/aaa999999> ls -l /tmp/drop | grep "2017-01-29" | egrep  '\.gz$' | tail -10
+ ls -F -l /tmp/drop
+ tail -10
+ grep 2017-01-29
+ egrep \.gz$
-rw-r--r--   1 user1001      user1001           20 Jan 29  2017 pattern101_worker-2_2017-01-29-21:33:13.888.complete.gz
-rw-r--r--   1 user1001      user1001           20 Jan 29  2017 pattern101_worker-2_2017-01-29-21:48:14.632.complete.gz
-rw-r--r--   1 user1001      user1001           20 Jan 29  2017 pattern101_worker-2_2017-01-29-22:03:19.098.complete.gz
-rw-r--r--   1 user1001      user1001           20 Jan 29  2017 pattern101_worker-2_2017-01-29-22:18:19.416.complete.gz
-rw-r--r--   1 user1001      user1001           20 Jan 29  2017 pattern101_worker-2_2017-01-29-22:33:19.878.complete.gz
-rw-r--r--   1 user1001      user1001           20 Jan 29  2017 pattern101_worker-2_2017-01-29-22:48:25.636.complete.gz
-rw-r--r--   1 user1001      user1001           20 Jan 29  2017 pattern101_worker-2_2017-01-29-23:03:26.515.complete.gz
-rw-r--r--   1 user1001      user1001           20 Jan 29  2017 pattern101_worker-2_2017-01-29-23:18:28.279.complete.gz
-rw-r--r--   1 user1001      user1001           20 Jan 29  2017 pattern101_worker-2_2017-01-29-23:33:33.059.complete.gz
-rw-r--r--   1 user1001      user1001           20 Jan 29  2017 pattern101_worker-2_2017-01-29-23:48:33.841.complete.gz
machine001:/home/aaa999999> cat zz.sh
+ cat zz.sh
#!/bin/bash
set -x

DROP_DIR=/tmp/drop
ARCHIVE_DIR=/tmp/arch
YESTERDAY="2017-01-29"
# move from drop dir
ls -1 ${DROP_DIR} | grep ${YESTERDAY} | egrep '\.gz$' | while read file; do
    mv  ${DROP_DIR}/$file ${ARCHIVE_DIR}
        echo 'File name is ' ${file}
done

답변1

ls -1파일 이름만 인쇄합니다. ls -l또한 다른 많은 것들을 인쇄합니다. 다른 하나는 숫자 1이고, 다른 하나는 소문자 el입니다.

-1출력이 파이프로 리디렉션되는 경우 "단일 열" 모드가 암시되므로 여기서는 이것이 필요하지 않습니다 .

ls하지만 실제로는 여기에 파이프가 전혀 필요하지 않습니다. 이 루프는 다음으로 대체될 수 있습니다.

for file in "$DROP_DIR/"*"$YESTERDAY"*.gz ; do 
    mv "$file" "$ARCHIVE_DIR"
    echo "File name is ${file#$DROP_DIR/}"
done

또한보십시오:L 분석Greg의 Bash 위키에 있습니다.

답변2

GNU 사용에 대한 권장사항 date:

yesterday=$( date -d yesterday +%F )
drop_dir=/tmp/drop
archive_dir=/tmp/arch

mkdir -p "$archive_dir"

mv -f "$drop_dir"/*"$yesterday"*.gz "$archive_dir"

여기에서는 "$drop_dir"/*"$yesterday"*.gz주어진 패턴과 일치하는 모든 파일이 확장됩니다. 이는 패턴이 수천 자로 확장되는 한 작동하며, 이 경우 쉘은 "인수 목록이 너무 길다"고 불평합니다.

또는 각 파일 이름을 이동할 때마다 반복하려는 경우( mv위 명령을 다음과 같이 변경하면 됩니다):

for name in "$drop_dir"/*"$yesterday"*.gz; do
    [ -f "$name" ] || continue
    mv "$name" "$archive_dir"
    printf 'Moved "%s"\n' "$name"
done

여기서 for루프는 이전 변형에서 사용된 것과 동일한 이름을 차례로 반복합니다. 각 이름은 $name(디렉터리 이름 포함) 에 저장됩니다 . 패턴과 일치하는 파일이 없으면 패턴은 확장되지 않은 상태로 유지됩니다. 이것이 바로 $name이동하기 전에 명시적으로 테스트하여 기존 파일과 실제로 일치하는지 확인하는 이유입니다.

또는 다음을 사용하여 find:

find "$drop_dir" -maxdepth 1 -type f -name "*$yesterday*.gz" \
    -print -exec mv {} "$archive_dir" ';'

여기서 이름은 주어진 패턴과 일치하는 일반 파일( )에 해당하는 이름 중에서 선택됩니다 find. 이러한 각 이름에 대해 파일을 대상 폴더로 이동하라는 호출이 이루어집니다. 그러나 호출하기 전에 파일 이름(경로 포함)이 터미널에 나열됩니다.$drop_dir-type f-namemvmv-print

-maxdepth 1옵션은 find하위 폴더로의 재귀를 중지합니다 $drop_dir.

답변3

귀하의 질문은 제게는 명확하지 않지만 귀하가 찾고 있는 것은 -o귀하의 egrep진술에 대한 옵션이라고 생각합니다.

 egrep -o "[^[:space:]]+\.gz$"

옵션 -o( --only-matching) egrep을 사용하면 일치하는 줄의 일치하는 부분만 출력됩니다. [^[:space:]]공백 문자를 제외한 모든 항목과 일치합니다 .

관련 정보