내용에 따라 파일 이동

내용에 따라 파일 이동

디렉토리는 하루 종일 수많은 파일을 수신합니다. 2번째 줄의 내용을 기준으로 파일을 선택하고 이동하고 싶습니다. 2번째 줄은 다음과 같습니다.

L054   EL621306DEM-A0-AGI378-0001  70807 201708072017081100061542364673600268
  • 조건 1: 열 8 및 9 = EL
  • 조건 2: 열 42/43/44/45 = 2017

( kshAIX 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을 사용하여 외부 표준 입력을 shfor 에 전달하여 표준 입력을 sh설정합니다 .mv

관련 정보