디렉토리는 하루 종일 수많은 파일을 수신합니다. 2번째 줄의 내용을 기준으로 파일을 선택하고 이동하고 싶습니다. 2번째 줄은 다음과 같습니다.
L054 EL621306DEM-A0-AGI378-0001 70807 201708072017081100061542364673600268
- 조건 1: 열 8 및 9 = EL
- 조건 2: 열 42/43/44/45 = 2017
( ksh
AIX 7.1에서 사용됨)
답변1
GNU 도구 사용(GNU 쉘 또는 ksh를 지원하는 기타 쉘)프로세스 교체( <(...)
), GNU xargs
또는 FreeBSD와 유사한 호환( -a
, -r
, -0
), GNU mv
( , -t
), GNU awk
( nextfile
다른 구현에서도 지원됩니다. 지원되지 않는 경우 무시되지만 효율성은 떨어집니다):
xargs -r0a <(
find dir -type f -exec awk 'FNR == 2 {
if (substr($0, 8, 2) == "EL" && substr($0, 42, 4) == "2017")
printf "%s\0", FILENAME
nextfile}' {} +) echo mv -it /somewhere
echo
(만족스러우면 삭제)
GNU가 아닌 시스템에서는 다음과 같이 변경할 수 있습니다.
{
find dir -type f -exec awk -v q="'" '
function quote_for_xargs(s) {
gsub(q, q "\\" q q, s)
gsub("\n", q "\\\n" q, s)
return q s q
}
FNR == 2 {
if (substr($0, 8, 2) == "EL" && substr($0, 42, 4) == "2017")
print quote_for_xargs(FILENAME)
nextfile
}' {} + | xargs sh -c '
[ "$#" -eq 0 ] || exec echo mv -i "$@" /somewhere <&3 3<&-' sh
} 3<&0
( 만족스러우면 삭제하세요 echo
).
즉, find
모든 텍스트 파일에 대한 호출이 있습니다. awk
에서 각 파일의 awk
두 번째 줄( FNR==2
)에 대해 조건이 충족되면 파일 이름이 적절한 형식으로 인쇄됩니다 xargs
(xargs 입력은 작은따옴표, 큰따옴표 및 백슬래시를 사용하여 공백이나 개행 문자로 구분된 단어 목록으로 처리됩니다). 구분 기호 또는 서로를 이스케이프하는 데 사용할 수 있습니다. 예를 들어, 이름이 ./That's tough.log
지정된 파일 은 './That'\''s tough.log'
.
xargs
가능한 많은 인수를 에 전달하려면 이 입력을 허용합니다 . 대상 디렉터리가 마지막 인수여야 하므로 래퍼가 sh
필요합니다 . 파일이 동일한 디렉토리에 있기 때문에 동일한 이름을 가진 두 파일을 다른 디렉토리로 이동하면 데이터가 손실될 수 있기 때문에 sh
이를 원합니다 . -i
우리에게 꼭 필요한 mv
표준 입력 ( -i
프롬프트용)아니요는 에서 오는 파이프 find
이므로 임시 fd 3을 사용하여 외부 표준 입력을 sh
for 에 전달하여 표준 입력을 sh
설정합니다 .mv