모든 bash 파일에 .sh 확장명 추가

모든 bash 파일에 .sh 확장명 추가

여러 파일이 있는 디렉터리가 있는데 그 중 일부는 bash 스크립트이지만 파일 이름에 .sh 확장명이 포함되어 있지 않습니다. -type 옵션으로 파일 형식을 확인하려면 file 명령을 사용해야 한다는 것과 xargs를 사용하여 출력을 리디렉션하여 파일 이름을 원래 이름 + .sh 확장자로 바꿀 수 있다는 것도 알고 있습니다. 문제는 모든 명령을 함께 연결하는 방법이나 bash ASCII 텍스트 전용 실행 파일의 파일 형식을 찾는 방법을 모른다는 것입니다. 간단한 명령으로 이 작업을 수행하는 방법을 아시나요?

답변1

표준 shebang 라인을 설정하면 file(최소 버전 5.39) 이를 감지할 수 있어야 합니다.

$ echo '#!/usr/bin/env bash' > 1
$ echo '#!/bin/bash' > 2
$ echo '#!/usr/bin/bash' > 3
$ file *
1: Bourne-Again shell script, ASCII text executable
2: Bourne-Again shell script, ASCII text executable
3: Bourne-Again shell script, ASCII text executable

그래서 우리는 이것을 할 수 있어야 합니다:

for path in ./*
do
    if [[ "$(file "$path")" = "${path}: Bourne-Again shell script, ASCII text executable" ]]
    then
        mv "$path" "${path}.bash"
    fi
done

이는 위의 예제 파일에서 작동합니다(그리고 공백 문자를 포함하거나 하이픈으로 시작하거나 개행 문자로 끝나는 파일 이름을 포함하여 특이한 파일 이름에도 작동해야 합니다).

$ ls
1.bash  2.bash  3.bash

이건 아마도아니요이것은 파일에 shebang 줄이 없는 경우에 작동합니다(이는 다음과 같은 파일에 적합합니다).다른 스크립트에서 얻음또는 shebang 줄이 잘못되었습니다(예:#!/bin/sh).

(저는 ".sh"보다 더 명시적이기 때문에 ".bash"를 사용했습니다.)

답변2

find이것이 작업을 수행하지는 않지만 kann이 grep파일 디렉토리를 재귀적으로 검색할 필요는 없습니다 -r(파일 이름이 와일드카드를 통해 전달되는 경우에도 해당).

grep -lIw '^#!.*bash' dir/!(*.sh) | xargs -I_ mv _ _.sh

grep-r 목차모든 하위 디렉터리의 모든 파일을 검색합니다(여기에서는 사용되지 않음).

grep은 일치하는 각 파일 이름을 인쇄하는 -l것과 유사 -H하지만 일반 출력을 억제합니다. 또한 첫 번째 일치 후에는 -q또는 유사하게 중지됩니다.-m1

grep은 -I바이너리 파일을 제외하고 텍스트 파일만 처리합니다.

grep-w 세게 때리다전체 단어만 일치합니다(일치하지 않음).세게 때리다편집하다)


정규식^ #!줄의 시작 부분만 일치합니다(#과 일치하지 않음).#!)

모든 바이트 = 모든 문자열 .과 일치하는 정규식*.*


경로 이름 확장(와일드카드) *.sh이 file.sh 패턴과 일치합니다.

확장된 와일드카드는 !(pattern)패턴을 제외한 모든 항목과 일치합니다.

ls는 dir/!(*.sh)모든 파일을 나열합니다목차들어오지 못하게 하다디렉토리/file.sh문서


매개변수-I 무늬매개변수는 각 위치에 삽입됩니다.무늬_이 예에서는 다음을 사용합니다.

mv   _     _  .sh
mv file1 file1.sh
mv file2 file2.sh

관련 정보