awk 프로그램의 경로에서 파일 이름 추출


21

awk 스크립트가 있고 CSV 파일을 전달했습니다.

awk -f script.awk /home/abc/imp/asgd.csv

내가하고있는 일은에서 FILENAME을 얻는 것 script.awk입니다. FILENAME이 전체 경로를 알려줍니다. 내가 awk에 있기 때문에 나는 사용할 수 없다 basename FILENAME.

print FILENAME;
/home/abc/imp/asgd.csv

나는 이것을 이것으로 시도했다. script.awk

echo $FILENAME | awk -F"/" '{print $NF}'

하지만 내에서 이것을 실행할 수 없습니다 script.awk. 어떻게 얻을 수 asgd.csvAWK 프로그램 내에서?

답변:


33

몇 가지 옵션 :

awk '
  function basename(file) {
    sub(".*/", "", file)
    return file
  }
  {print FILENAME, basename(FILENAME)}' /path/to/file

또는:

awk '
  function basename(file, a, n) {
    n = split(file, a, "/")
    return a[n]
  }
  {print FILENAME, basename(FILENAME)}' /path/to/file

의 그 구현합니다 basename같은 코너의 경우 일반적인 경우에 작동하지만 안 basename /path/to/x///그들이 대신 빈 문자열을 반환 곳 x또는 /그들이 어디에 대신 빈 문자열을 반환 /일반 파일, 그렇게는 안하지만.

첫 번째 경로는 파일 경로 (마지막까지 /)에 현재 로케일에서 유효한 문자를 형성하지 않는 바이트 시퀀스가 ​​포함되어 있으면 제대로 작동 하지 않습니다 (일반적으로 이러한 종류의 일은 UTF-8 로케일에서 발생합니다. 비트 단일 바이트 문자 세트). 모든 바이트 시퀀스가 ​​유효한 문자를 형성하는 로케일을 C로 고정하여이 문제를 해결할 수 있습니다.


5
함수를 소개하지 않고 기존 awk 스크립트에서 쉽게 작동하는 코드가 필요한 경우 다음을 사용해야합니다 n = split(FILENAME, a, "/"); basename=a[n];.. 변수 sub를 실제로 변경 하기 때문에 사용하지 마십시오 FILENAME(awk는 값으로 호출을 사용하기 때문에 함수에서 문제가되지 않습니다).
shiri

10

이 awk one-liner를 사용해보십시오.

$ awk 'END{ var=FILENAME; split (var,a,/\//); print a[5]}' /home/abc/imp/asgd.csv
asgd.csv

3
또는awk 'END{ var=FILENAME; n=split (var,a,/\//); print a[n]}' /home/abc/imp/asgd.csv
Avinash Raj

0

입력 CSV 또는 입력 파일 경로에서 직접 내보내는 가장 좋은 방법은 그것을 뒤집은 다음 1 열을 얻은 다음 다시 뒤집을 수 있습니다.

function getFileFromPath() {
    FileName=$1
    cat $FileName | while read Filename
    do
        echo $Filename| rev | awk -v FS='/' '{print $1}' | rev 
    done
}

또는 단순히

echo $FileNamePath| rev | awk -v FS='/' '{print $1}' | rev 

0

Awk의 스플릿 기능 사용

이를 수행하는 한 가지 방법은 split 기능을 사용하는 것입니다. 예를 들면 다음과 같습니다.

awk '{idx = split(FILENAME, parts, "/"); print parts[idx]; nextfile}' /path/to/file

이것은 심지어 여러 파일에서 작동합니다. 예를 들면 다음과 같습니다.

$ awk '{idx = split(FILENAME, parts, "/"); print parts[idx]; nextfile}' \
      /etc/passwd /etc/group
passwd
group

0

basename명령을 사용할 수 있는 시스템에서 awksystem()기능 또는 expression | getline var구조를 사용하여 외부 basename명령 을 호출 할 수 있습니다 . 이는 Stephane의 답변 에서 언급 된 코너 사례를 설명하는 데 도움이 됩니다.

$ awk '{cmd=sprintf("basename %s",FILENAME);cmd | getline out; print FILENAME,out; exit}' /etc///passwd
/etc///passwd passwd
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.