줄을 읽고 조건에 따라 줄 시작 부분에 파운드 기호(#)를 추가합니다.

줄을 읽고 조건에 따라 줄 시작 부분에 파운드 기호(#)를 추가합니다.

여러 줄의 텍스트가 있는 파일을 읽고 해당 줄에서 명령을 실행하는 bash 스크립트가 있습니다. 명령이 작동할 때도 있지만 실패할 때도 있습니다. 명령이 성공적으로 실행되는 텍스트 줄과 명령이 실패한 줄의 시작 부분에 파운드 기호(#)를 추가하고 싶습니다. 다음에 스크립트를 실행할 때 다시 시도할 수 있도록 그대로 추가해야 합니다. #으로 시작하는 줄은 실행되지 않습니다.
내 현재 스크립트는 다음과 같습니다 -

COUNT=1
while read -r LINE; do
    if [[ ($LINE != \#*) && !(-z "${LINE// }") ]] ; then
        echo "${LINE}"
        # execute "$LINE"
        if [ $? -eq 0 ]; then
            echo OK # Append pound (#) at the start of the line
        else
            echo FAIL # Keep the line in the source file
        fi
    fi
    COUNT=$(( $COUNT + 1 ))
done < $SRC_FILE

보시다시피 조건이 이미 있으므로 이러한 조건 echo OKecho FAIL코드 줄만 바꾸면 됩니다. 나는 노력했다이 답변, 그러나 결국 모든 줄이 삭제됩니다. 나는 그것을 원하지 않고 파일에 실패한 줄을 유지하고 싶습니다.

사용해 보았 sed으나 별 효과가 없는 것 같습니다.

sed -n "${COUNT}s/^/#/" $SRC_FILE >> $SRC_FILE

이를 수행할 수 있는 방법이 있습니까?

추신: Linux와 Mac 터미널, 특히 Mac zsh의 bash와 zsh에서 실행되도록 만들고 싶습니다.

고쳐 쓰다:
나는 다음 명령을 시도했다

sed "${COUNT}s/.*/#&/" $SRC_FILE >$SRC_FILE

소스 파일에서 모든 줄을 제거하고 비워 두지만 출력 파일을 변경하면 원본 소스 파일에서 여전히 읽고 있기 때문에 마지막 줄에 #만 추가하더라도 작동합니다.

답변1

다음을 수행할 수 있습니다.

#! /bin/sh -
src_file=/path/to/file
{
  while read <&3 -r line; do
    case $line in
      ('#'*) ;;
      (*)
         if eval " $line" 3<&- 4>&-; then
           echo OK
           line="# $line"
         else
           echo FAIL
         fi
    esac
    printf '%s\n' "$line" >&4
  done
  mv -- "$src_file.new" "$src_file"
} 3< "$src_file" 4> "$src_file.new"

파일의 각 줄은 sh코드로 평가됩니다. 이러한 행에서 특정 또는 특정 기능을 사용하는 경우 해당 기능을 또는 sh로 바꾸십시오 bash.zshbashzsh

여기서는 파일을 생성하고 마지막으로 file.new이름을 바꿉니다. (GNU) 또는 (FreeBSD/macOS) file도 어느 정도 동일합니다. 일반적으로 특정 파일을 읽는 동안 해당 파일에 쉽게 쓸 수 없습니다.sed -ised -i ''

답변2

sed [command] file > file당신이 발견했듯이, 당신의 의지를 사용하는 것은 당신이 원하는 것을 하지 않습니다. 리디렉션하면 의 내용이 지워지고 file의 출력으로 대체됩니다 sed.

당신이 해야 할 일은 sed내장된 함수를 사용하여 파일을 그 자리에서 수정하는 것입니다:

sed --in-place "$COUNTs/^/#/" file

관련 정보