파일의 처음 n 바이트 삭제


32

나는 극단적 인 문제가 있으며 상상할 수있는 모든 솔루션이 복잡합니다. 내 유닉스 / 리눅스 경험에 따르면 쉬운 방법 이 있어야 한다.

에서 각 파일의 처음 31 바이트를 삭제하고 싶습니다 /foo/. 각 파일은 충분합니다. 글쎄, 누군가가 상상할 수없는 놀랍도록 쉬운 솔루션을 제공 할 것이라고 확신합니다. 어쩌면?


2
awk / sed / ed 솔루션은 줄 지향적이므로 첫 번째 줄이 31 자 이상인지 모른다면 합병증이 발생합니다.
glenn jackman

답변:


28
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

또는 Gilles의 제안 덕분에 더 빠릅니다.

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 기본 꼬리는 마음에 들지 않습니다.

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

/usr/xpg4/bin/tail 두 구문 모두에 좋습니다.


1
dd여기에 제안하는 것은 과잉 tail이며 더 적절합니다 (더 간단하고 킬러 오타의 위험이 적으며 stderr에 가짜 메시지가 없음).
Gilles 'SO- 악마 그만해'

네 말이 맞아 보통 바이너리 파일을 처리 할 때 텍스트 파일을 처리하기위한 명령은 피하지만 "tail + 32c"는 여기서 작동합니다.
jlliagre

1
@jlliagre : 당신은 작성했습니다 cut (꼬리가 아니어야합니까? ... 그대로, 그것은 나를 위해 작동하지 않습니다 ...
Peter.O

물론 꼬리입니다. 불일치해서 죄송합니다.
jlliagre

@jlliagre : Solaris에서는을 /usr/xpg4/bin앞서 나가야 /usr/bin합니다 PATH. 그렇지 않으면 1990 년대 초에 갇힐 것입니다. 많은 유니스 (예 : GNU, BusyBox)는 더 이상 히스토리 +32c구문을 지원하지 않으며 +32cPOSIX에서 요구 하는 파일을 의미합니다 .
Gilles 'SO- 악마 그만'

12

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

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

찾은 find모든 파일에 대해 아래의 파일 또는 모든 파일 을 나열 /foo/하고 위의 두 파일 만 실행하면 $file됩니다.


1
bs와 skip 값을 바꾸면 성능이 향상됩니다.
jlliagre

10

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

파일이 실제로 큰 경우 (하나의 파일이라도 두 개의 사본을 보유 할 수있을 정도로 큰 경우) 이 스레드에서 언급 한 기술 중 하나를 사용할 수 있습니다 .


2

Ex 모드에서 Vim을 사용할 수 있습니다 :

for each in /foo/*
do
  ex -sc '%!tail -c+32' -cx "$each"
done
  1. % 모든 줄을 선택하십시오

  2. ! 명령을 실행

  3. x 저장하고 닫습니다

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.