새 파일을 생성하지 않고도 CLI에서 파일 시작 부분에 일부 텍스트를 추가할 수 있습니까?

새 파일을 생성하지 않고도 CLI에서 파일 시작 부분에 일부 텍스트를 추가할 수 있습니까?

file1다음을 포함하는 두 개의 파일이 있습니다.

hello world
hello bangladesh  

그리고 file2다음을 포함합니다 -

 Dhaka in Bangladesh
 Dhaka is capital of Bangladesh  

다음으로 업데이트하고 싶습니다 file2. -

hello world
hello bangladesh 
Dhaka in Bangladesh
Dhaka is capital of Bangladesh

이 작업은 -

cat file1 file2 >> file3
mv file3 file2  

그러나 새 파일을 만들고 싶지 않습니다. sed활용이 가능하지 않을까 싶었습니다 .

답변1

물론 가능합니다.

(거의 모든 텍스트 편집기가 작동하는 방식이기 때문에 "내부"에서 임시 파일 생성 가능성에 대해 걱정하지 않는 한, 배후에서 임시 파일 생성 가능성을 피하는 것이 완전히 불가능하다고 말하는 것은 아니지만 이 답변 덮지 않습니다.)

printf '%s\n' '0r file1' x | ex file2

이것은 POSIX 호환 명령입니다.ex, POSIX 지정 비시각적 선행자vi.

printf이는 편집기에 명령을 제공하는 데에만 사용됩니다. 출력은 printf다음과 같습니다

0r file1
x

x저장하고 나가시면 됩니다.

r"지정된 파일의 내용을 읽는다"입니다.

0읽은 텍스트가 배치되어야 하는 줄 번호를 지정합니다.

답변2

표준 도구를 사용하여 파일을 수정하는 방법은 많지 않습니다. 이렇게 하는 것처럼 보이더라도 임시 파일(예: GNU sed -i)을 사용하고 있을 수 있습니다.

ex반면에 다음을 수행합니다.

 ex -n -c '0r file2' -c wq file1

ex는 라인 편집기이며 vim거기서 발전했기 때문에 이러한 명령이 익숙해 보일 수 있습니다. 와 동일한 작업 0r filename: 지정된 주소(줄 번호) 뒤에 지정된 파일을 삽입합니다. 여기서 줄번호는 0으로, 1번 줄 이전의 줄을 나타내는 가상의 줄입니다. 따라서 파일은 기존 텍스트 앞에 삽입됩니다.:0r filenamevim

그런 다음 wq저장하고 종료합니다.

이것이 "매우 깨지기 쉽다"는 아래의 설명을 발견하면 소금 한 알씩 받아들이십시오. 이를 스크립트에서 사용하려면 적절한 전제 조건 유효성 검사(파일 존재, 읽기/쓰기 가능 등)를 수행해야 합니다. 어쨌든 훌륭한 시나리오 작가가 하는 일이 바로 그것이다.

고쳐 쓰다:-n임시 파일 생성을 방지하는 것에 대한 OP의 우려를 해결하기 위해 뭔가를 추가했습니다 . 구현이 ex이것의 일부로 구현되었다고 가정하면(대부분의 최신 시스템의 경우와 마찬가지로) 이 플래그는 일반적인 스왑 파일 생성을 억제합니다.vimvim

답변3

all=$( cat file1 file2 )
echo "$all" > file2

작은 파일에만 작동합니다.

답변4

Jasen의 답변과 유사하게 이것이 유틸리티의 기초입니다.

암호스펀지패키지에더 많은 유틸리티거의 모든 프로그램(외부 프로그램이라도)이 적절한 기능을 가질 수 있도록 설계되었습니다. 기본적으로 STDIN에서 입력을 받아 수집된 출력을 파일 이름에 쓰지만 리디렉션하지는 않습니다.

아이디어가 마음에 들어서 실제 스펀지처럼 파일 대신 메모리에 데이터를 수집하는 유사한 작업을 만들었습니다.

이를 설명하는 쉘 스크립트는 다음과 같습니다.

# Utility functions: print-as-echo, print-line-with-visual-space.
pe() { for _i;do printf "%s" "$_i";done; printf "\n"; }
pl() { pe;pe "-----" ;pe "$*"; }

pl " Input files data2, data3:"
head data[23]
pe
ls -gGli data[23]

pl " Results, re-write file from memory, preserving inode:"
cat data[23] | ./absorb-memory-public data3
head -v data3
pe
ls -gGli data3

생산:

-----
 Input files data2, data3:
==> data2 <==
hello world
hello bangladesh 

==> data3 <==
Dhaka in Bangladesh
Dhaka is capital of Bangladesh  

1051395 -rw-r--r-- 1 30 Jan  7 08:58 data2
1052221 -rw-r--r-- 1 53 Jan  7 08:58 data3

-----
 Results, re-write file from memory, preserving inode:
==> data3 <==
hello world
hello bangladesh 
Dhaka in Bangladesh
Dhaka is capital of Bangladesh  

1052221 -rw-r--r-- 1 83 Jan  7 08:58 data3

핵심 Perl 코드는 매우 짧습니다(특히 오류 검사가 없으면 오류 검사를 추가하는 것이 바람직할 수 있음).

use warnings;
use strict;
use Carp;

# Avoid hang for argument matching "-version","--version", etc.
exit(0) if @ARGV && $ARGV[0] =~ /-version/;

my ( $file, $f, $memory );
$file = shift || croak("Need a filename.");

$/ = 0777;      # Slurp the entire STDIN
$memory = do { local $/; <> };

open( $f, ">", $file ) || die " Cannot open file \"$file\" for write.\n";

print $f "$memory";

다음 시스템에서 실행됩니다.

OS, ker|rel, machine: Linux, 3.16.0-4-amd64, x86_64
Distribution        : Debian 8.9 (jessie) 
bash GNU bash 4.3.30
perl 5.20.2

행운을 빕니다... 건배, drl

관련 정보