명령어로 파일을 사용하여 출력을 잘라내지 않고 같은 파일로 리다이렉트하려면 어떻게 해야 합니까?
기본적으로 파일에서 입력 텍스트로 가져와 해당 파일에서 행을 제거한 후 출력을 동일한 파일로 다시 보냅니다.더 명확해진다면 이 선들을 따라가는 뭔가가 있을 거야
grep -v 'seg[0-9]\{1,\}\.[0-9]\{1\}' file_name > file_name
그런데 이렇게 하면 빈 파일이 나와요.무슨 생각 있어?
이런 일에는 스펀지를 사용하세요.모레유틸리티의 일부입니다.
다음 명령을 사용해 보십시오.
grep -v 'seg[0-9]\{1,\}\.[0-9]\{1\}' file_name | sponge file_name
bash가 먼저 리디렉션을 처리하고 나서 명령을 실행하기 때문에 이 작업을 수행할 수 없습니다.따라서 grep가 file_name을 참조할 때는 이미 비어 있습니다.임시 파일을 사용할 수 있습니다.
#!/bin/sh
tmpfile=$(mktemp)
grep -v 'seg[0-9]\{1,\}\.[0-9]\{1\}' file_name > ${tmpfile}
cat ${tmpfile} > file_name
rm -f ${tmpfile}
해서 '아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 이런mktemp
Tmp 파일을 작성하는데 POSIX가 아님을 주의해 주세요.
대신 sed 사용:
sed -i '/seg[0-9]\{1,\}\.[0-9]\{1\}/d' file_name
이 간단한 것을 시험해 보다
grep -v 'seg[0-9]\{1,\}\.[0-9]\{1\}' file_name | tee file_name
이번에는 파일이 공백이 되지 않고 출력도 단말기에 출력됩니다.
연산자리다이렉션 연산자)는수 없습니다.>
★★★★★★★★★★★★★★★★★」>>
)는같은 은, , 을 작성입니다).「 」이것은, 우선 순위가 높고, 커맨드를 기동하기 전에 파일을 작성/재인증하기 때문입니다..tee
,sponge
,sed -i
쓸 수 툴 " " " " " " " " " " " " " " " " " " " " )sort file -o file
를 참조해 주세요.
기본적으로 입력을 동일한 원본 파일로 리디렉션하는 것은 의미가 없으며 적절한 인플레이스 에디터를 사용해야 합니다(예: Ex editor(Vim의 일부).
ex '+g/seg[0-9]\{1,\}\.[0-9]\{1\}/d' -scwq file_name
여기서:
'+cmd'
/-c
- Ex/Vim 명령어 실행g/pattern/d
- global을 사용하여 패턴과 일치하는 선을 제거합니다.help :g
)-s
모드 「」)man ex
)-c wq
- 행행:write
★★★★★★★★★★★★★★★★★」:quit
, 명령어
하면 .sed
(다른 답변에서 이미 나타난 바와 같이) 동일한 것을 달성한다. 단, (다른 답변에서 이미 나타난 바와 같이)-i
)는 비표준 FreeB입니다.SD 확장자(Unix/Linux 간에 다르게 동작할 수 있음)는 기본적으로 파일 편집기가 아닌 스트림 편집기입니다.참조: Ex 모드는 실제로 사용됩니까?
이 질문이 검색 엔진에서 가장 중요한 결과이기 때문에, 여기 https://serverfault.com/a/547331을 기반으로 한 하위 셸 대신 하위 셸을 사용하는 원라이너가 있습니다.sponge
OS 바닐라 설치의 (OS X는 바닐라 가 아닙니다).
echo "$(grep -v 'seg[0-9]\{1,\}\.[0-9]\{1\}' file_name)" > file_name
일반적인 경우는 다음과 같습니다.
echo "$(cat file_name)" > file_name
편집. 위의 솔루션에는 몇 가지 경고가 있습니다.
printf '%s' <string>
echo <string>
때문에, 「」를 포함한-n
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★- 명령어 치환에서는 줄바꿈이 삭제되므로(이것은 bash와 같은 셸의 버그/기능입니다), 다음과 같은 포스트픽스 문자를 추가해야 합니다.
x
다음과 같은 임시 변수의 매개 변수 확장을 통해 외부로 출력하고 제거합니다.${v%x}
. - 변수
$v
.$v
표현식 전체를 괄호 안에 넣어 이전 값을 보존해야 합니다. - 또 다른 버그가 bash와 같이 인쇄할 수 없는 입니다.
null
출력에서 가져옵니다.는 이것을 했습니다.dd if=/dev/zero bs=1 count=1 >> file_name
으로 보다cat file_name | xxd -p
echo $(cat file_name) | xxd -p
벗겨져 있습니다.따라서 이 답변은 Lynch가 지적한 바와 같이 바이너리 파일이나 인쇄 불가능한 문자를 사용하는 어떤 것에 사용해서는 안 됩니다.
일반적인 솔루션(약간 느리고 메모리 사용량이 많으며 인쇄 불가능한 문자를 제거하는 방법)은 다음과 같습니다.
(v=$(cat file_name; printf x); printf '%s' ${v%x} > file_name)
https://askubuntu.com/a/752451에서 테스트:
printf "hello\nworld\n" > file_uniquely_named.txt && for ((i=0; i<1000; i++)); do (v=$(cat file_uniquely_named.txt; printf x); printf '%s' ${v%x} > file_uniquely_named.txt); done; cat file_uniquely_named.txt; rm file_uniquely_named.txt
인쇄 대상:
hello
world
, 「」를 호출하고 있습니다.cat file_uniquely_named.txt > file_uniquely_named.txt
「 」:
printf "hello\nworld\n" > file_uniquely_named.txt && for ((i=0; i<1000; i++)); do cat file_uniquely_named.txt > file_uniquely_named.txt; done; cat file_uniquely_named.txt; rm file_uniquely_named.txt
빈 문자열을 인쇄합니다.
대용량 파일(아마 2GB 또는 4GB 이상)에서 테스트한 적이 없습니다.
나는 이 대답을 Hart Simha와 Kos로부터 빌렸다.
One liner 대안 - 파일의 내용을 변수로 설정합니다.
VAR=`cat file_name`; echo "$VAR"|grep -v 'seg[0-9]\{1,\}\.[0-9]\{1\}' > file_name
이것은 매우 가능성이 있습니다.출력을 쓸 때까지 다른 파일에 쓸 필요가 있습니다.파일 기술자를 연 후 파일을 삭제하지만 쓰기 전에 이 작업을 수행할 수 있습니다.
exec 3<file ; rm file; COMMAND <&3 >file ; exec 3>&-
또는 한 줄 한 줄 이해하기 위해 다음과 같이 하십시오.
exec 3<file # open a file descriptor reading 'file'
rm file # remove file (but fd3 will still point to the removed file)
COMMAND <&3 >file # run command, with the removed file as input
exec 3>&- # close the file descriptor
COMMAND가 제대로 실행되지 않으면 파일 내용이 손실되기 때문에 여전히 위험한 작업입니다.이는 COMMAND가 0이 아닌 종료 코드를 반환하는 경우 파일을 복원함으로써 완화할 수 있습니다.
exec 3<file ; rm file; COMMAND <&3 >file || cat <&3 >file ; exec 3>&-
셸 함수를 정의하여 사용하기 쉽게 할 수도 있습니다.
# Usage: replace FILE COMMAND
replace() { exec 3<$1 ; rm $1; ${@:2} <&3 >$1 || cat <&3 >$1 ; exec 3>&- }
예:
$ echo aaa > test
$ replace test tr a b
$ cat test
bbb
또한 원본 파일의 전체 복사본이 유지됩니다(세 번째 파일 설명자가 닫힐 때까지).Linux 를 사용하고 있고 처리 중인 파일이 너무 커서 디스크에 두 번 들어갈 수 없는 경우 이 스크립트를 체크하면 이미 처리된 블록의 할당을 해제하면서 지정된 블록별로 파일을 파이핑할 수 있습니다.항상 그렇듯이 사용 페이지의 경고를 읽습니다.
이하와 같은 것을 실현합니다.sponge
필요 없이 할 수 있습니다.moreutils
:
shuf --output=file --random-source=/dev/zero
그--random-source=/dev/zero
파트 트릭shuf
조작을 전혀 하지 않고 조작할 수 있기 때문에, 조작을 변경하지 않고 입력을 버퍼링 할 수 있습니다.
그러나 성능상 임시 파일을 사용하는 것이 가장 좋습니다.일반적인 방법으로 이 기능을 수행할 수 있도록 제가 작성한 함수는 다음과 같습니다.
# Pipes a file into a command, and pipes the output of that command
# back into the same file, ensuring that the file is not truncated.
# Parameters:
# $1: the file.
# $2: the command. (With $3... being its arguments.)
# See https://stackoverflow.com/a/55655338/773113
siphon()
{
local tmp file rc=0
[ "$#" -ge 2 ] || { echo "Usage: siphon filename [command...]" >&2; return 1; }
file="$1"; shift
tmp=$(mktemp -- "$file.XXXXXX") || return
"$@" <"$file" >"$tmp" || rc=$?
mv -- "$tmp" "$file" || rc=$(( rc | $? ))
return "$rc"
}
이것은 내가 직면한 대부분의 경우에 꽤 효과가 있다.
cat <<< "$(do_stuff_with f)" > f
해 주세요.$(…)
바꿈, 줄 바꿈, 줄 바꿈, 줄 바꿈, 줄 바꿈,<<<
최종적인 새로운 라인이 보증되기 때문에 일반적으로 결과는 마법처럼 만족합니다.(여기 문자열 참조)man bash
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
완전한 예:
#! /usr/bin/env bash
get_new_content() {
sed 's/Initial/Final/g' "${1:?}"
}
echo 'Initial content.' > f
cat f
cat <<< "$(get_new_content f)" > f
cat f
이렇게 해도 파일이 잘리지 않고 다음과 같은 결과를 얻을 수 있습니다.
Initial content.
Final content.
여기서 사용하는 기능은 명확성과 확장성을 위해 사용했지만, 필수는 아닙니다.
일반적인 사용 사례는 JSON 에디션입니다.
echo '{ "a": 12 }' > f
cat f
cat <<< "$(jq '.a = 24' f)" > f
cat f
그 결과:
{ "a": 12 }
{
"a": 24
}
그리고 또ed
)sed -i
# cf. http://wiki.bash-hackers.org/howto/edit-ed
printf '%s\n' H 'g/seg[0-9]\{1,\}\.[0-9]\{1\}/d' wq | ed -s file_name
POSIX Awk에서는 slurp를 사용할 수 있습니다.
!/seg[0-9]\{1,\}\.[0-9]\{1\}/ {
q = q ? q RS $0 : $0
}
END {
print q > ARGV[1]
}
이거 드셔보세요
echo -e "AAA\nBBB\nCCC" > testfile
cat testfile
AAA
BBB
CCC
echo "$(grep -v 'AAA' testfile)" > testfile
cat testfile
BBB
CCC
저는 보통 티 프로그램을 사용합니다.
grep -v 'seg[0-9]\{1,\}\.[0-9]\{1\}' file_name | tee file_name
temp 파일을 스스로 작성 및 삭제합니다.
언급URL : https://stackoverflow.com/questions/6696842/how-can-i-use-a-file-in-a-command-and-redirect-output-to-the-same-file-without-t
'programing' 카테고리의 다른 글
PowerShell에서 특정 변수가 글로벌 범위에 존재하는지 여부를 테스트하려면 어떻게 해야 합니까? (0) | 2023.04.19 |
---|---|
행의 첫 번째 N자를 삭제하기 위한 unix 명령어는 무엇입니까? (0) | 2023.04.19 |
프로세스가 정지된 경우 프로세스를 재시작하는 bash 스크립트를 작성하려면 어떻게 해야 합니까? (0) | 2023.04.19 |
WPF 텍스트 상자에 스택 패널이 채워지지 않음 (0) | 2023.04.19 |
WPF - Data Trigger와 트리거를 조합하는 방법 (0) | 2023.04.19 |