Fortran 소스 코드 들여쓰기, 들여쓰기되지 않은 특수 줄에 들여쓰기 전파

Fortran 소스 코드 들여쓰기, 들여쓰기되지 않은 특수 줄에 들여쓰기 전파

원격 저장소에 커밋하기 전에 일부 자동 서식을 개선하기 위해 자체 스크립트를 작성하려고 합니다. 내 IDE에서 들여쓰기 가이드를 사용하고 있는데 내 언어의 자동 포맷터(FORTRAN)가 빈 줄 들여쓰기를 지원하지 않습니다. 내가 본질적으로 원하는 것은 sed파일의 줄을 반복하고 줄이 비어 있으면 줄과 동일한 수의 공백이 생길 때까지 줄에 공백을 추가하는 것입니다.그 위에(따라서 첫 번째 줄은 무시하십시오). 이것을 커밋 전 후크의 일부로 사용하고 싶기 때문에 파일이 요구 사항을 통과하고 수정되지 않았다면 좋을 것입니다.

공백 이 해당하는 형식화되지 않은 파일의 예 >:

Start of document - First line is ignored
Second line has text and is therefore ignored
>>>>Third line has four spaces so below (empty line) should have 4 spaces added.

>>>>>>>>Third line has 8 spaces so below (empty line) should have 8 spaces added.

End of document

원하는 출력:

Start of document - First line is ignored
Second line has text and is therefore ignored
>>>>Third line has four spaces so below (empty line) should have 4 spaces added.
>>>>
>>>>>>>>Third line has 8 spaces so below (empty line) should have 8 spaces added.
>>>>>>>>
End of document

그리고 이와 관련하여 느낌표로 시작하는 줄을 들여쓰고 싶습니다.열 1에(앞의 공백 없이) 위 줄 수준으로 이동합니다(왜냐하면 내가 사용하는 자동 포맷터가 이를 지원하지 않기 때문입니다).

공백 이 해당하는 형식화되지 않은 파일의 예 >:

Start of document - First line is ignored
! Second line starts with exclamation mark in column 1 so it is indented to level of above line
>>>>Third line has 4 spaces to start
!This should have 4 spaces added to it because the first character is ‘!’ and above line has 4
>>>>>>>>This line has 8 spaces
>>>>>>>>!This line shouldn’t be changed as it begins with a space, not an exclamation mark.
End of document

원하는 출력:

Start of document - First line is ignored
! Second line starts with exclamation mark in column 1 so it is indented to level of above line
>>>>Third line has 4 spaces to start
>>>>!This should have 4 spaces added to it because the first character is ‘!’ and above line has 4
>>>>>>>>This line has 8 spaces
>>>>>>>>!This line shouldn’t be changed as it begins with a space, not an exclamation mark.
End of document

저는 bash 스크립팅을 처음 접했기 때문에 솔루션 작동 방식에 대한 설명이 훌륭할 것이며 도움을 주셔서 미리 감사드립니다!

편집: 댓글에서 요청한 대로 이미지를 텍스트로 대체했습니다!

답변1

사용 sed:

sed -n \
    -e '/^!/ { G; s/\(.*\)\n\(.*\)/\2\1/; }' \
    -e '/^$/g' \
    -e p \
    -e 's/^\( *\).*/\1/' \
    -e h file

이는 일련의 sed편집 표현식을 사용하여 원하는 들여쓰기를 수행합니다. 스크립트는 예약된 공간( 의 편집 불가능한 보조 버퍼 sed)을 사용하여 현재 들여쓰기를 여러 공백 문자로 저장합니다.

!줄의 첫 번째 위치가 a로 시작하면 첫 번째 표현식이 트리거됩니다. 이 표현식은 개행 문자를 구분 기호로 사용하여 예약된 공간에 있는 내용을 현재 행의 끝에 추가한 다음 버퍼의 두 부분을 교환하여 개행 문자를 제거합니다. !현재 들여쓰기 수준으로 -line을 들여쓰기 합니다 .

두 번째 표현식은 빈 줄에 대해 실행되고 예약된 공간에 있는 내용으로 대체됩니다. 빈 줄에 적절한 양의 공백을 추가하는 역할을 합니다.

세 번째 표현식은 편집 버퍼의 현재 내용을 출력합니다. 현재 올바르게 들여쓰기되어 있으므로(-line !, 빈 줄 또는 아직 수정하지 않은 다른 줄로 인해) 이를 명시적으로 수행하고 나머지 부분을 처리할 수 있도록 곧 수정해야 합니다. 문서를 올바르게.

마지막 두 작업은 공백 들여쓰기 끝에서 현재 줄을 자른 다음 루프를 통해 다음 번에 사용할 수 있도록 나머지 들여쓰기를 예약된 공간에 저장합니다. 예를 들어 [[:blank:]]탭이나 공백을 사용하여 들여쓰기와 일치 하도록 마지막 교체의 공백을 바꿉니다 .

답변2

이와 같은 작업은 awk또는 같은 언어에서 가장 잘 수행 됩니다 perl(sed에는 변수가 없으므로).

다음 한 줄의 Perl 코드는 두 요구 사항 모두에 적합합니다. 필요한 줄의 시작 부분에 공백이 추가되어 각 줄의 끝을 나타내는 cat -A것을 볼 수 있도록 출력을 파이프로 연결했습니다 .$

첫 번째 명령문은 변수의 내용을 $spaces행의 시작 부분( )에 추가합니다. $_행이 비어 있거나 !첫 번째 입력 행에서 -로 시작하면 $spaces비어 있게 됩니다 . 두 번째 문은 현재 줄(있는 경우)의 시작 부분에 있는 공백을 캡처하여 $spaces다음 입력 줄에서 사용할 수 있도록 준비합니다.

참고: 여기서 사용된 은 \h가로 공백(ASCII 파일의 공백과 탭 및 일부 유니코드 공백 문자)을 의미합니다. 공백 문자만 사용하려면 \h단일 공백으로 변경하세요: ($spaces) = (/^( *)/).

첫 번째 입력 파일:

$ perl -p -e 'if (/^($|!)/) { $_ = $spaces . $_ };
              ($spaces) = (/^(\h*)/)' input1.txt  | cat -A
Start of document - First line is ignored$
Second line has text and is therefore ignored$
    Third line has four spaces so below (empty line) should have 4 spaces added.$
    $
        Third line has 8 spaces so below (empty line) should have 8 spaces added.$
        $
End of document$

두 번째 파일:

$ perl -p -e 'if (/^($|!)/) { $_ = $spaces . $_ };
              ($spaces) = (/^(\h*)/)' input2.txt  | cat -A
Start of document - First line is ignored$
! Second line starts with exclamation mark in column 1 so it is indented to level of above line$
    Third line has 4 spaces to start$
    !This should have 4 spaces added to it because the first character is '!' and above line has 4$
        This line has 8 spaces$
        !This line shouldn't be changed as it begins with a space, not an exclamation mark.$
End of document$

또한 참고: 이는 파일(수정 여부에 관계없이)을 표준 출력으로 인쇄합니다. 원본 파일을 수정하려면 -i명령줄에 perl 옵션을 추가하세요. 이는 sedperl -i옵션과 유사합니다. 자세한 내용 확인 man perlrun및 검색 -i\[extension\]) - 다음 사항에 특히 주의하시기 바랍니다.

-i동일한 이름의 새 파일을 만들기 전에 원본 파일의 이름이 바뀌거나 삭제되므로 Unix 스타일 소프트 링크와 하드 링크는 유지되지 않습니다 .

git파일의 inode 번호가 변경되더라도 내용이 변경된 경우에만 신경 쓰지 않는 것 같습니다. 그러나 하드 링크를 유지해야 하거나 입력 파일이 아직 변경되지 않은 경우 덮어쓰고 싶지 않은 경우 리디렉션하십시오. 임시 파일에 저장하고 임시 파일이 다른 경우 diff에만 덮어씁니다.cmp

관련 정보