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

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

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

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

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

텍스트 파일에 뒤에 공백이 있는지 확인하고 그렇지 않은 공백은 건너뛰는 편리한 방법이 있습니까?

답변1

수정해야 할 줄이 있는지 확인하기 위해 first 를 사용할 수 있습니다. 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이 실행되면 -maxlength가 검색에 사용됩니다.
  • {} \; 는 에 전달될 파일의 ​​이름을 나타내며 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

관련 정보