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