파일의 처음 n 바이트 삭제 / 리눅스 경험에

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

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



답변

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 두 구문 모두에 좋습니다.


답변

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

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

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


답변

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

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


답변

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

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

  2. ! 명령을 실행

  3. x 저장하고 닫습니다


답변