`cut`을 사용하여 파일을 제자리에서 변경할 수 있습니까?


답변:


14

당신은 할 수 없습니다. ed 또는 GNU sed 또는 perl을 사용하거나 컨텐츠 뒤에서 새 파일을 작성하는 등의 작업을 수행합니다.

ed휴대용 :

ed foo <<EOF
1,$s/^\([^,]*\),\([^,]*\),\([^,]*\).*/\1,\3/
w
q
EOF

GNU sed:

sed -i -e 's/^\([^,]*\),\([^,]*\),\([^,]*\).*/\1,\3/' foo

펄 :

perl -i -l -F, -pae 'print @F[1,3]' foo

cut, 새 파일 만들기 (스크립트가 중단되면 다시 실행할 수 있으므로 권장) :

cut -d , -f 1,3 <foo >foo.new &&
mv -f foo.new foo

cut파일을 제자리에 교체합니다 (의 소유권과 권한은 유지 foo하지만 중단되지 않도록 보호해야 함).

cp -f foo foo.old &&
cut -d , -f 1,3 <foo.old >foo &&
rm foo.old

cut기반 방법 중 하나를 사용하는 것이 좋습니다 . 이렇게하면 비표준 도구에 의존하지 않고 작업에 가장 적합한 도구를 사용할 수 있으며 인터럽트 동작을 제어 할 수 있습니다.


.old전체 변경 방법 보다 우수echo "$(cut -d , -f 1,3 <foo)" > foo
GypsyCosmonaut

1
@GypsyCosmonaut 아니요,“더 나은”것은 아닙니다. 더 연약하다. 유일한 장점은 입력하기가 더 짧다는 것입니다. 메소드의 주요 문제점은 입력 파일을 처리하거나 출력을 쓰는 중에 오류가 발생하면 데이터가 손실된다는 것입니다. 또한 이진 데이터에서는 작동하지 않습니다. 출력은 첫 번째 null 바이트에서 잘립니다. 텍스트 파일을 사용하더라도 파일 끝에서 빈 줄을 제거합니다. 큰 파일의 경우 데이터가 셸 메모리에 문자열로 저장되어야하기 때문에 실패 할 수 있습니다 (이 경우 데이터가 손실됨을 기억하십시오).
Gilles 'SO- 악의를 그만두십시오

oO 감사합니다, null 바이트에 문제가 있을지 몰랐습니다
GypsyCosmonaut

나는 이것이 더 간단하다고 생각한다 :cut -d , -f 1,3 foo > foo.new rm foo mv foo.new foo
LoMaPh

@LoMaPh 실제로 이전 파일의 이름을 변경 한 이유를 모르겠습니다. 새 파일의 이름을 바꾸는 것보다 이점이 없습니다. 단계가 필요하지 않기 때문에 더 간단합니다 rm foo. 원자 rm foo이기 mv foo.new foo때문에을 호출해서는 안됩니다 . 이전 버전을 제거하고 새 버전을 동시에 배치합니다.
Gilles 'SO- 악의를 그만두십시오

23

우분투 (및 debian ) 의 moreutils 패키지 에는라는 프로그램이 있으며 문제를 해결합니다.sponge

남자 스폰지에서 :

sponge은 표준 입력을 읽고 지정된 파일에 씁니다. 쉘 재 지정과 달리 스폰지는 출력 파일을 열기 전에 모든 입력을 흡수합니다. 이를 통해 동일한 파일에서 읽고 쓰는 파이프 라인을 제한 할 수 있습니다.

다음과 같은 작업을 수행 할 수 있습니다.

cut -d <delim> -f <fields> somefile | sponge somefile

9

나는 그것이 cut혼자 사용하는 것이 가능하다고 생각하지 않습니다 . 맨 페이지 나 정보 페이지에서 찾을 수 없습니다. 당신은 같은 것을 할 수 있습니다

mytemp=$(mktemp) && cut -d" " -f1 file > $mytemp && mv $mytemp file

mktempcut출력을 파이프 할 수있는 비교적 안전한 임시 파일을 만듭니다 .


1

vim-way를보십시오 :

$ ex -s +'%!cut -c 1-10' -cxa file.txt

그러면 파일이 내부에서 편집됩니다 (먼저 백업도 수행됨).

또는 사용 grep, sed또는 gawk.


0

POSIX Awk와 함께 slurp를 사용할 수 있습니다 :

cut -b1 file | awk 'BEGIN{RS="";getline<"-";print>ARGV[1]}' file


0

글쎄, cut읽기보다 적은 출력을 생성하기 때문에 다음을 수행 할 수 있습니다.

cut -c1 < file 1<> file

즉, stdin file을 읽기 전용 모드로 file열리고 stdout 을 자르지 않고 읽기 + 쓰기 모드로 열어야합니다 ( <>).

그렇게 cut하면 파일 자체를 덮어 씁니다. 그러나 나머지 파일은 그대로 유지됩니다. 예를 들어 다음이 file포함 된 경우 :

foo
bar

출력은 다음과 같습니다 :

f
b
bar

f\nb\n대체 foo\n되었지만 bar여전히 있습니다. cut완료 한 후 파일을 잘라야합니다 .

을 사용하면 명령이 성공하면 파일 설명자에서 호출되는 것을 제외하고 작동하는 연산자로 ksh93수행 할 수 있습니다 . 그래서:<>;<>ftruncate()

cut -c1 < file 1<>; file

다른 쉘에서는 다음 ftruncate()과 같은 다른 수단을 통해 비아 를 수행해야합니다 .

{ cut -c1 < file; perl -e 'truncate STDOUT, tell STDOUT';} 1<> file

perl그것을 위해 호출 하는 것은 여기에서 약간 과잉입니다. 특히 그것이 perl쉽게 다음 cut과 같은 일 을 할 수 있다는 것을 고려하면 :

perl -pi -e '$_ = substr($_, 0, 1)' file

실제 내부 다시 쓰기와 관련된 모든 방법을 사용하여 작업이 중간에 중단되면 파일이 손상 될 수 있습니다. 임시 두 번째 파일을 사용하면이 문제를 피할 수 있습니다.

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