필요한 경우에만 텍스트 파일에서 후행 공백을 제거하십시오.

필요한 경우에만 텍스트 파일에서 후행 공백을 제거하십시오.

다음을 사용하여 후행 공백을 제거하고 있습니다.

sed -i 's/[ \t]*$//' *.txt

그러나 이 명령은 모든 파일을 다시 작성합니다.

텍스트 파일에 공백이 있는지 판단하고 공백 없이 건너뛸 수 있는 편리한 방법이 있습니까?

답변1

먼저 수정해야 할 줄이 있는지 찾기 위해 사용할 수 있지만 grep최악의 경우 파일을 두 번 읽게 됩니다(마지막 줄만 수정해야 하는 경우).

for f in ./*.txt; do
    grep -q '[[:blank:]]$' "$f" &&
      sed -i 's/[[:blank:]]*$//' "$f"
done

답변2

한 가지 방법은 find/grep/sed다음과 같습니다.

find . -maxdepth 1 -type f -name '*.txt' \
  -exec grep -q '[[:blank:]]$' {} \; \
  -exec sed -Ei -e 's/[[:blank:]]+$//' {} +
  • 1이 현재 디렉토리 내에서 작동하는 경우 -max깊이를 사용한 찾기입니다.
  • {} \; 전달되는 파일의 이름을 참조하고 grep명령 \;끝 표시기인 셸 메타 문자 세미콜론을 이스케이프합니다. 에 도달하도록 탈출합니다 -exec. 또는 다음과 같이 작성할 수도 있습니다.';'
  • {} +{}당신은 지금 이미 알고 있으며 이는 +가능한 한 많은 파일 이름을 전달한다는 것을 의미합니다 (기본적으로 현재 결과 중 sed하나를 전달하는 대신 호출하기 전에 인수로 사용할 목록을 축적합니다 ). 이를 통해 호출 횟수를 최소화할 수 있습니다 .{}find{}sedsed

답변3

편집을 수행하고 차이가 있는 경우에만 원본 파일을 대체하십시오.

for file in *.txt
do
    sed 's/[ \t]*$//' < "$file" > "$file.tmp.$$" || continue
    cmp -s -- "$file" "$file.tmp.$$" ||
      cat < "$file.tmp.$$" > "$file" ||
      continue
    rm -f -- "$file.tmp.$$"
done

답변4

다음은 다음을 기반으로 합니다.로아이마의 생각모든 파일에 대해 표현식을 실행 sed하지만 실제로 수정된 파일만 유지합니다.

더 적은 호출을 수행하여 이를 수정합니다 sed.

printf '%s\0' ./*.txt |
xargs -0 sed -i.bak 's/[[:blank:]]$//

그런 다음 파일을 검토하여 *.txt원본과 비교하고 보관하려는 파일을 선택할 수 있습니다.

for name in ./*.txt; do
    if cmp -s "$name" "$name.bak"; then
        # keep original
        mv "$name.bak" "$name"
    else
        # keep modified
        rm "$name.bak"
    fi
done

또는 한 번에 두 가지를 모두 수행합니다.

printf '%s\0' ./*.txt |
xargs -0 sh -c '
    sed -i.bak "s/[[:blank:]]$//" "$@"
    for name do
        if cmp -s "$name" "$name.bak"; then
            mv "$name.bak" "$name"
        else
            rm "$name.bak"
        fi
    done' sh

관련 정보