나는 극단적 인 문제가 있으며 상상할 수있는 모든 솔루션이 복잡합니다. 내 유닉스 / 리눅스 경험에 따르면 쉬운 방법 이 있어야 한다.
에서 각 파일의 처음 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
-
%
모든 줄을 선택하십시오 -
!
명령을 실행 -
x
저장하고 닫습니다