수천 개의 파일을 처리하는 스크립트의 출력을 덮어쓰는(>) 대신 실수로 추가(>>)했지만 파일의 약 20%에 대해서만 이 작업을 수행했습니다(스크립트의 병렬 인스턴스를 5개 실행했습니다). 기본적으로 10줄의 텍스트, 빈 줄, 그리고 다시 동일한 10줄의 텍스트가 있습니다.
- 이 파일을 어떻게 찾을 수 있나요?
- 두 번째 반복을 어떻게 삭제합니까?
1이 2보다 훨씬 더 중요합니다.
수천 개의 파일을 처리하는 스크립트의 출력을 덮어쓰는(>) 대신 실수로 추가(>>)했지만 파일의 약 20%에 대해서만 이 작업을 수행했습니다(스크립트의 병렬 인스턴스를 5개 실행했습니다). 기본적으로 10줄의 텍스트, 빈 줄, 그리고 다시 동일한 10줄의 텍스트가 있습니다.
- 이 파일을 어떻게 찾을 수 있나요?
- 두 번째 반복을 어떻게 삭제합니까?
1이 2보다 훨씬 더 중요합니다.
(이 질문은 문제를 보여줍니다)
고쳐 쓰다:
내용을 꼼꼼히 살펴봤습니다. 중복된 내용이 포함된 파일의 구조는 다음과 같습니다.
<empty line>
<text>
<empty line>
<empty line>
<same text>
<empty line>
중복된 내용이 없는 파일은
<empty line>
<text>
<empty line>
즉, 가운데에 두 개의 빈 줄이 있는 것입니다. 첫 번째 줄의 시작점은 위의 텍스트이고, 두 번째 줄의 시작점은 아래의 텍스트입니다. 텍스트의 상단과 하단은 빈 줄로 둘러싸여 있습니다.
답변1
다른 작업을 수행하기 전에 현재 데이터를 백업하십시오. 문제가 발생하면 언제든지 이 복사본으로 되돌릴 수 있습니다. 예를 들어 다음을 사용할 수 있습니다
tar
.tar cfz /path/to/backup-files.tar.gz /path/to/directory-to-backup/
일반적으로 다음과 같이 해야 합니다.안 돼요관심 있는 모든 데이터의 고유한 복사본을 처리하세요. 반드시 백업을 해두시거나, 복사본을 만들어서 작업하시기 바랍니다. 즉, 당신은해야합니다언제나변경 사항을 되돌리고 실수를 취소할 수 있는 쉽고 빠른 방법을 스스로에게 제공하십시오.
\n
"좋은" 파일에 3번 연속으로 개행 문자( )가 나오지 않을 것이라고 확신한다면 다음을 시도해 보십시오.복사일부 "좋은" 파일과 "나쁜" 파일:perl -i -0777 -p -e 's/\n{3,}.*/\n\n/' filenames
이렇게 하면 3개의 줄 바꿈(예: 텍스트 줄 끝에 있는 줄 바꿈과 두 개의 빈 줄이 뒤따름)에서 파일 끝까지의 모든 내용이 제거되고 두 개의 줄 바꿈(한 줄은 텍스트 줄 끝)으로 대체됩니다. 파일 끝에 추가하려는 빈 줄).
모든 파일아니요3개의 연속된 줄 바꿈(즉, 복구할 필요가 없는 "좋은" 파일)이 있으며 수정되지 않습니다.
방금 Perl로 처리한 파일("좋음" 및 "나쁨")을 확인하십시오.
예상과 일치하면 파일이 포함된 디렉터리의 모든 파일에 대해 Perl 스크립트를 실행합니다. 예를 들어,
find
모든 파일에.txt
확장명이 있는 경우:find /path/to/directory -type f -name '*.txt' -exec \ perl -i -0777 -p -e 's/\n{3,}.*/\n\n/' {} +
(
find
실제 디렉토리와 파일 이름에 맞게 명령을 조정하십시오)
답변2
파일을 찾으려면 다중 문자 RS 및 ENDFILE에 GNU awk를 사용하십시오.
$ awk -v RS='\n{2}' '$0==p{f=1} {p=$0} ENDFILE{print FILENAME, (f ? "dups" : "uniq"); p=f=""}' file1 file2
file1 dups
file2 uniq
위의 내용은 이 입력에서 실행됩니다.
$ head file{1,2}
==> file1 <==
<text>
<text>
==> file2 <==
<text>
답변3
그리고 perl
:
find . -type f -size +1c -exec perl -l -0777 -e '
while (<<>>) {
$size = length; $half = $size / 2;
if ($size % 2 == 0 && substr($_, 0, $half) eq substr($_, $half)) {
print "$ARGV is one of them";
truncate $ARGV, $half or warn "truncate $ARGV: $!";
}
}' {} +
답변4
에서는 연관 배열을 zsh
사용하여 파일 경로를 해당 내용에 매핑할 수 있습니다 . $mapfile
이렇게 하면 첫 번째 절반과 두 번째 절반을 쉽게 비교하고 해당 위치에서 파일을 업데이트할 수 있습니다.
#! /bin/zsh -
zmodload zsh/mapfile || exit
set +o multibyte
for file in **/*(ND.L+1); do
text=$mapfile[$file]
size=$#text
if (( size % 2 == 0 )); then # even size
(( half = size / 2 ))
if [[ $text[1,half] = $text[half+1,-1] ]]; then
print -r -- $file is one of them
mapfile[$file]=$text[1,half] # or truncate -s$half -- $file
fi
fi
done
(검증되지 않은).
**/*(ND.L+0)
대신 **/*(ND.L+0m-1)
지난 24시간(또는 지난 3시간 등) **/*(ND.mh-3)
에 마지막으로 수정된 파일 만 처리 할 수 있습니다 . D
숨겨진 파일이 더 이상 문제가 되지 않으면 삭제하세요. 제거되거나 주석 처리되어 mapfile[$file]=...
일치하는 파일만 수정하지 않고 나열됩니다.