파이프를 ll
사용하여 별칭을 만들려고 합니다 . awk
다음을 사용하여 아포스트로피를 피하려고합니다.답변.
alias lh= `ll -h | awk {'print $9, \"-\" ,$5, \"-\", $8, \"-\",$7, $6'}`
하지만 작동하지 않는 것 같습니다.
bash
및 의 콘솔 출력은 zsh
동일합니다.
awk: cmd. line:1: {print $9, \"-\" ,$5, \"-\", $8, \"-\",$7, $6}
awk: cmd. line:1: ^ backslash not last character on line
awk: cmd. line:1: {print $9, \"-\" ,$5, \"-\", $8, \"-\",$7, $6}
awk: cmd. line:1: ^ syntax error
입장 시
alias lh= `ll -h | awk {'print $9, "-" ,$5, "-", $8, "-",$7, $6'}`
출력은 비어 있음을 의미합니다.
답변1
별칭 정의에는 몇 가지 구문 문제가 있습니다. 그러나 첫 번째 문제는 출력을 구문 분석하는 것입니다.ls
매우 낙담함이를 포함하는 코드는 결국 공백, 탭 및 줄 바꿈과 같은 "사소하지 않은" 문자가 포함된 파일을 우연히 발견하게 되기 때문입니다. 또한 특히 타임스탬프의 출력 형식은 파일의 실제 "오래된" 정도에 따라 변경될 수 있습니다. 즉, awk
실제 파일에 따라 입력에 공백으로 구분된 "필드"가 많거나 적을 수 있음을 의미합니다. 필드 변경(예: "오래된 파일"의 연도에서 "최근 파일"의 시간으로) 이 두 가지 측면은 @steeldriver가 별칭 "취약성"이라고 부르는 것입니다.
"명백한" 질문은 다음과 같습니다.
- 그 뒤에 공백이 있습니다
=
. 이렇게 하면 별칭이lh
정의되지 않은 상태로 남게 됩니다(적어도bash
). - 별칭 정의를 백틱(
`
)으로 묶어 "세 번째 수준" 참조를 생성할 수 있습니다. 그러나 역따옴표는 명령 대체 구문입니다(현재는 더 이상 사용되지 않음)lh
.ll | awk ...
파이프라인 콘솔 출력그리고 실행을 시도저것명령으로. ll
존재하거나 최소한 별칭으로 미리 정의된 명령을 사용하고 있습니다ls -l
. 이것은 사실일 수도 있고 아닐 수도 있습니다.- 프로그램
awk
이 잘못된 순서로 작은따옴표와 중괄호로 시작됩니다. 올바른 구문은 입니다awk ' { ... } '
.
이것이 쉘 스크립트의 일부인 경우 다음을 통해 실행해야 할 수도 있습니다.shellcheck
는 많은 Linux 배포판에서 독립 실행형 도구로 사용되어 많은 구문 관련 오류를 잡을 수도 있습니다.
문제에 대한 즉각적인 해결책은 실제로 올바른 인용 및 이스케이프입니다. 다음과 같은 것을 시도해 볼 수 있습니다.
alias lh="ls -lh | awk '{print \$9, \"-\" ,\$5, \"-\", \$8, \"-\",\$7, \$6}'"
여기서 별칭은 의 모든 항목이고 " ... "
, 의 입력은 awk
명시적으로 로 선언되고 ls -lh
, awk
프로그램은 작은따옴표로 묶이고, 프로그램 내의 필드 참조는 awk
"별칭이 정의될 때" 위치 인수 백슬래시 이스케이프에 의해 쉘이 조기 해석으로부터 보호됩니다( awk
그래서 실제로 $9
는 비어 있을 수 있는 쉘 인스턴스의 9번째 위치 인수로 대체되는 대신 것처럼 처리됩니다 .
하지만
다음에서 찾은 제안당신이 링크한 질문에 대한 답변 중 하나- 함수를 정의하는 것은 "참조 지옥"(@ilkkachu가 언급했듯이)에서 벗어나는 더 좋은 방법입니다.
lh() { ls -lh | awk '{print $9, "-" ,$5, "-", $8, "-",$7, $6}'; }
더 명확하고 이해하기 쉽습니다.
ls
구문 분석을 완전히 피하고 다음find
기반 별칭을 사용하는 것이 좋습니다 .lh() { find . -maxdepth 1 -type f ! -name ".*" -printf "%f - %s - %TY - %Td %Tb\n"; }
printf
형식 지정 옵션을 사용하여find
필요한 파일 속성을 안정적으로 출력합니다. 유일한 단점은-h
사람이 읽을 수 있는 크기 옵션이 없다는 것입니다.이 필터는 숨겨진 파일을 무시하는 표준 동작을
! -name ".*"
시뮬레이션하는 데 사용됩니다 .ls
나열하려면 이 섹션을 생략할 수 있습니다.