디렉토리에 파일 목록이 있습니다 /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
-name
mv
mv
-print
이 -maxdepth 1
옵션은 find
하위 폴더로의 재귀를 중지합니다 $drop_dir
.
답변3
귀하의 질문은 제게는 명확하지 않지만 귀하가 찾고 있는 것은 -o
귀하의 egrep
진술에 대한 옵션이라고 생각합니다.
egrep -o "[^[:space:]]+\.gz$"
옵션 -o
( --only-matching
) egrep
을 사용하면 일치하는 줄의 일치하는 부분만 출력됩니다. [^[:space:]]
공백 문자를 제외한 모든 항목과 일치합니다 .