![awk 스크립트의 파이핑](https://rvso.com/image/23956/awk%20%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8%EC%9D%98%20%ED%8C%8C%EC%9D%B4%ED%95%91.png)
의 출력을 구문 분석하는 데 ls
사용되는 래퍼를 작성하려고 합니다 . 지금은 프로그램을 두 개의 파일 과 . 의 유일한 목적은 의 출력 을 . 그것은 다음과 같습니다:awk
ls -lhF
my_ls.sh
my_ls.awk
my_ls.sh
ls -lhF
my_ls.awk
#!/bin/bash
ls -lhF "$@" | my_ls.awk
ls -lhF
awk 스크립트 자체를 통해 출력을 읽을 수 있는 방법이 있는지 궁금합니다 .
편집하다:나의 주요 목적은 현재 디렉토리 내용을 멋진 트리 형태로 보여주는 스크립트를 작성하는 것입니다. 초안 버전은 my_ls.awk
다음과 같습니다.
#!/usr/bin/awk -f
( NF >= 9 ) {
print "|-- [" $5 "] " $9
}
이것내가 지금까지 도달한 곳은 여기이다.
답변1
의 출력을 구문 분석하면 안 된다는 다른 조언에 동참하겠습니다 ls
. 따라서 이는 나쁜 예입니다. 그러나 보다 일반적인 문제로서 awk 스크립트를 awk
.
#!/bin/bash
ls -lhF "$@" | awk '
( NF >= 9 ) {
print "|-- [" $5 "] " $9
}'
awk 스크립트에 '
(작은 따옴표) 문자가 포함되어야 하는 경우 이를 인용해야 합니다. '\''
(닫는 작은 따옴표, 리터럴 작은 따옴표, 여는 작은 따옴표)를 사용하십시오.
인용하지 않으려면 다음을 사용할 수 있습니다.여기 문서대신에. 하지만 표준 입력을 사용하여 awk에 입력을 제공하고 스크립트를 제공할 수 없기 때문에 어색합니다. 추가 파일 설명자를 사용해야 합니다(참조:추가 파일 설명자는 언제 사용합니까? 파일 설명자 및 쉘 스크립팅).
#!/bin/bash
ls -lhF "$@" | awk -f /dev/fd/3 3<<'EOF'
( NF >= 9 ) {
print "|-- [" $5 "] " $9
}
EOF
getline
awk 내에서 함수와 파이프 구성을 사용하여 다른 명령의 입력을 읽을 수 있습니다 . awk가 기본적으로 사용하도록 설계된 방식은 아니지만 작동하도록 만들 수 있습니다. 오류가 발생하기 쉬운 기본 셸에 대한 파일 이름 인수를 인용해야 합니다. 그리고 처리할 텍스트가 예상 소스(표준 입력 또는 명령줄에 명명된 파일)에서 나오지 않기 때문에 결국 블록에 모든 코드가 포함됩니다 BEGIN
.
#!/usr/bin/awk -f
BEGIN {
command = "ls -lhF"
for (i = 1; i <= ARGC; i++) {
arg = ARGV[i];
gsub("'", "'\\''", arg);
command = command " '" arg "'";
}
ARGC = 0; for (i in ARGV) delete ARGV[i];
while ((command | getline) > 0) {
if (NF >= 9) { print "|-- [" $5 "] " $9 }
}
}
간단히 말해서, 쉘이 잘하는 것(예: 명령을 함께 파이핑하는 것)에는 쉘을 사용하고, 잘하는 것(예: 텍스트 처리)에는 awk를 사용하십시오.
답변2
무엇을 하려는지 잘 모르겠지만 발생할 수 있는 한 가지 문제는 마지막 필드로 간주되지만 그렇게 간주되지 않는 awk
필드(기본 구문 분석을 통해)를 인쇄하는 것 입니다. 예. ls
awk
-rw-r--r-- | 433k | filename-with-no-spaces
-rw-r--r-- | 1k | link containing spaces -> /home/user/filename-with-no-spaces
어떻게든 마지막 필드를 분리해야 합니다 ls
. 아래에서 취한 접근 방식은 모든 이전 필드와 구분 기호의 길이를 찾는 것입니다. 나머지는 파일 이름 필드(링크 대상과 같은 기타 정보 포함)입니다.
아래 스크립트는 가변 너비의 최대 너비를 결정합니다.크기필드(출력 형식화에 필요) 이 너비를 얻는 방법에는 여러 가지가 있습니다. 예.(1)awk
메인 루프에서 출력 의 각 라인을 처리 ls
하고 후속 처리를 위해 각 라인을 배열에 추가하는 데 사용됩니다 END{ }
. 또는(2) 출력을 ls
임시 파일에 쓴 다음 awk
해당 파일을 처리하도록 합니다. 아래에 표시된 방법은 다음을 사용합니다.(2).
ls
의 경우와 같이 의 출력은 예상치 못한, 단순하지 않은 결과를 원하는 방식으로 보낼 수 있으므로 일반적 으로 구문 분석 요구 사항에 더 적합하도록 출력을 link
사용하고 사용자 정의하는 것이 더 안전합니다 .find
f=7 # the number of (multi-space) delimiters before the start of the filename
myls="$(mktemp)" # a temp file to hold output from `ls`
w=$(ls --color=always -lFHk ~/ |tee "$myls" |awk '{print $5}' |wc -L) # max width of size field
h=k # size unit
awk --re-interval -v"f=$f" -v"w=$w" -v"h=$h" '
NF >= f {
regex = "^([^ ]+ +){"f"}"
match( $0, regex ) # find start of name field
printf( "%s | %"w"s%s | %s\n", $1, $5, h, substr( $0, RLENGTH ))
}' "$myls"
rm "$myls"
답변3
바퀴를 재발명하는 것을 피하고 대신 tree
디렉토리의 파일/폴더 및 하위 디렉토리 파일/폴더를 표시하는 를 사용하는 것이 좋습니다.
tree(1) - Linux 매뉴얼 페이지
이름
tree - 트리와 같은 형식으로 디렉토리 내용을 나열합니다.
개요
tree [-adfghilnopqrstuvxACDFNS] [-L 수준 [-R]] [-H baseHREF] [-T 제목] [-o 파일 이름] [--nolinks] [-P 패턴] [-I 패턴] [--inodes] [ --device] [--noreport] [--dirsfirst] [--version] [--help] [--filelimit #] [디렉토리 ...]
설명
Tree는 깊이 들여쓰기된 파일 목록을 생성하는 재귀적 디렉터리 목록 프로그램입니다. LS_COLORS 환경 변수가 설정되고 출력이 tty로 이루어지며 -C 플래그가 사용되는 경우 색상은 dircolors와 같이 지원됩니다. 인수가 없으면 tree는 현재 디렉터리의 파일을 나열합니다. 디렉토리 인수가 주어지면 tree는 주어진 디렉토리에서 발견된 모든 파일 및/또는 디렉토리를 차례로 나열합니다. 발견된 모든 파일/디렉터리 나열이 완료되면 tree는 나열된 파일 및/또는 디렉터리의 총 수를 반환합니다.
기본적으로 기호 링크가 발견되면 기호 링크가 참조하는 경로가 링크 이름 뒤에 다음 형식으로 인쇄됩니다.
이름 -> 실제 경로
'-l' 옵션이 주어지고 심볼릭 링크가 실제 디렉토리를 참조하면 tree는 마치 실제 디렉토리인 것처럼 심볼릭 링크의 경로를 따릅니다.