다음을 사용하여 후행 공백을 제거하고 있습니다.
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
{}
sed
sed
답변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