파일의 처음 n바이트 삭제

파일의 처음 n바이트 삭제

나는 극심한 문제에 직면해 있고 내가 생각할 수 있는 해결책은 모두 복잡합니다. 내 UNIX/Linux 경험을 토대로~ 해야 하다간단한 방법이다.

각 .txt 파일의 처음 31바이트를 삭제하고 싶습니다 /foo/. 각 파일의 길이는 충분합니다. 글쎄요, 누군가는 제가 상상할 수 없는 매우 간단한 해결책을 제시할 것이라고 확신합니다. 어쩌면 어이?

답변1

for file in /foo/*
do
  if [ -f "$file" ]
  then
    dd if="$file" of="$file.truncated" bs=31 skip=1 && mv "$file.truncated" "$file"
  fi
done

또는 Giles의 제안에 감사드립니다.

for file in /foo/*
    do
      if [ -f $file ]
      then
        tail +32c $file > $file.truncated && mv $file.truncated $file
      fi
    done

참고: Posix tail은 "+32c" 대신 "-c +32"를 지정하지만 Solaris의 기본 tail은 이를 좋아하지 않습니다.

   $ /usr/bin/tail -c +32 /tmp/foo > /tmp/foo1
    tail: cannot open input

/usr/xpg4/bin/tail두 구문 모두 괜찮습니다.

원래 파일 권한을 유지하려면

... && mv "$file.truncated" "$file"

통과

... && cat "$file.truncated" "$file" && rm "$file.truncated"

답변2

다음 명령은 처음 31바이트를 잘라냅니다 $file( $file~임시 복사본으로 사용됨).

dd if="$file" of="$file~" bs=1 skip=31
mv "$file~" "$file"

find아래의 모든 파일을 나열 /foo/하고 발견된 각 파일에 대해 위의 두 파일을 실행하면 됩니다 $file.

답변3

tail -c +32입력에서 처음 31바이트를 뺀 값을 출력합니다. (예, 매개변수는 하나씩 다릅니다.) 파일을 그 자리에서 편집하려면,스펀지를 사용하세요루프에서 또는 해당 기능이 없고 귀찮게 하고 싶지 않은 경우 셸에서 해당 작업을 수행합니다.

for x in /foo/*; do tail -c +32 "$x" | sponge "$x"; done
for x in /foo/*; do tail -c +32 "$x" >"$x.new" && mv "$x.new" "$x"; done

어떤 이유로(예: 정전) 명령이 중단되면 어디서 중단했는지 파악하기 어려울 수 있습니다. 별도의 디렉터리에 새 파일을 작성하면 작업이 더 쉬워집니다.

mkdir /foo.tmp
cd /foo
for x in *; do tail -c +42 -- "$x" >"/foo.tmp/$x" && rm -- "$x"; done
mv /foo.tmp/* /foo
rmdir /foo.tmp

파일이 매우 큰 경우(예: 두 개의 복사본을 가질 수 있을 만큼 크거나 심지어 하나의 복사본이라도 문제가 되는 경우) 다음을 사용할 수 있습니다.이 스레드에서 언급된 기술 중 하나.

답변4

블록 크기 1을 사용하는 것은 dd매우 느립니다. 다음과 같이 건너뛰기를 바이트 단위로 지정하는 동안 더 큰 블록 크기를 사용할 수 있습니다.

dd iflag=skip_bytes if=infile.txt of=outfile.txt skip=31 bs=1M

관련 정보