디렉토리에 많은 텍스트 파일이 있으며 디렉토리에있는 모든 파일의 마지막 줄을 제거하고 싶습니다.
어떻게하니?
디렉토리에 많은 텍스트 파일이 있으며 디렉토리에있는 모든 파일의 마지막 줄을 제거하고 싶습니다.
어떻게하니?
답변:
GNU가 있다면이 멋진 oneliner를 사용할 수 있습니다 sed
.
sed -i '$ d' ./*
현재 디렉토리에서 숨겨지지 않은 각 파일의 마지막 행을 제거합니다. -i
GNU 스위치 sed
는 제자리에서 작동하는 것을 의미 하고 마지막 줄 ( 마지막 의미 및 삭제 의미) 을 삭제하도록 '$ d'
명령합니다 .sed
$
d
-i
하고 있기 때문에 이것이 무의미하지만, 이전 버전의 일부 sed
가 $
와 d
(또는, 일반적으로 패턴과 명령 사이).
*(.)
하면 일반 파일 을 구할 수 있습니다 . 다른 쉘에 대해서는 알 수 없습니다.
디렉토리에 일반 파일 이외의 파일이 있거나 파일 이름에 공백 / 줄 바꿈이있는 파일이 있으면 다른 모든 답변에 문제가 있습니다. 다음은 관계없이 작동하는 것입니다.
find "$dir" -type f -exec sed -i '$d' '{}' '+'
find "$dir" -type f
: 디렉토리에서 파일을 찾습니다 $dir
-type f
일반 파일입니다.-exec
찾은 각 파일에 대해 명령을 실행하십시오.sed -i
: 파일을 제자리에 편집하십시오.'$d'
: d
마지막 ( $
) 행을 삭제 ( )합니다 .'+'
: find에 인수를 계속 추가하도록 지시합니다 sed
(@zwol 덕분에 각 파일에 대해 개별적으로 명령을 실행하는 것보다 조금 더 효율적입니다).하위 디렉토리로 하강하지 않으려면에 인수 -maxdepth 1
를 추가 할 수 있습니다 find
.
find
더 효율적으로 작성되었습니다 find $dir -type f -exec sed -i '$d' '{}' '+'
.)
-print0
전체 명령에 포함되어 있지 않은 이유는 무엇입니까?
-depth 0
작동하지 않습니다 (findutils 4.4.2) 대신 대신해야합니다 -maxdepth 1
.
-exec
.
GNU를 사용 sed -i '$d'
한다는 것은 전체 파일을 읽고 마지막 줄없이 사본을 만드는 것을 의미하지만 파일을 제자리에 잘리는 것이 훨씬 효율적입니다 (적어도 큰 파일의 경우).
GNU truncate
를 사용하면 다음을 수행 할 수 있습니다.
for file in ./*; do
[ -f "$file" ] &&
length=$(tail -n 1 "$file" | wc -c) &&
[ "$length" -gt 0 ] &&
truncate -s "-$length" "$file"
done
파일이 상대적으로 작 으면 파일 당 여러 명령을 실행하기 때문에 효율성이 떨어질 수 있습니다.
마지막 줄 바꿈 문자 다음에 마지막 줄 다음에 여분의 바이트가 포함 된 파일 또는 다른 말로 , 구분되지 않은 마지막 줄 이 있으면 tail
구현 에 따라 tail -n 1
해당 여분의 바이트 (GNU와 같은 tail
) 만 반환합니다 . 또는 마지막 (적절하게 구분 된) 줄과 여분의 바이트.
|wc -c
에 tail
전화? (또는 a ${#length}
)
${#length}
바이트 $(...)
가 아닌 문자 수를 계산 하고 테일링 줄 바꿈 문자를 제거하므로 ${#...}
모든 문자가 1 바이트 일지라도 1 만큼 줄어 듭니다 .
보다 편리한 접근 방식 :
for f in ./*
do
test -f "$f" && ed -s "$f" <<\IN
d
w
q
IN
done
나는 이것이 설명이 필요하다고 생각하지 않습니다 ...이 경우에는 기본적으로 마지막 줄을 선택하기 때문에 d
동일 하다는 것을 제외하고 .
재귀 적으로 검색하지 않으며 숨겨진 파일 (일명 도트 파일)을 처리하지 않습니다.
그것들을 편집하려면 디렉토리 안의 숨겨진 파일과 *를 일치시키는 방법을 참조하십시오$d
ed
[[]]
하면 []
POSIX와 완전히 호환됩니다. ( [[ ... ]]
Bashism이다.)
[[
비난은 아니지만 )
도트 파일을 포함하여 현재 디렉토리에서 재귀 적으로 시작하는 모든 파일에 대한 POSIX 호환 단일 라이너 :
find . -type f -exec sh -c 'for f; do printf "\$d\nx\n" | ex "$f"; done' sh {} +
를 들어 .txt
파일 만이 아닌 재귀 :
find . -path '*/*/*' -prune -o -type f -name '*.txt' -exec sh -c 'for f; do printf "\$d\nx\n" | ex "$f"; done' sh {} +
참조 :