여러 파일을 연결하지만 파일 이름을 섹션 헤더로 포함


352

터미널에서 하나의 큰 파일로 많은 텍스트 파일을 연결하고 싶습니다. cat 명령을 사용하여이 작업을 수행 할 수 있다는 것을 알고 있습니다. 그러나 각 파일의 파일 이름이 해당 파일의 "데이터 덤프"보다 앞에 오도록하고 싶습니다. 아무도 이것을하는 방법을 알고 있습니까?

내가 현재 가지고있는 것 :

file1.txt = bluemoongoodbeer

file2.txt = awesomepossum

file3.txt = hownowbrowncow

cat file1.txt file2.txt file3.txt

원하는 출력 :

file1

bluemoongoodbeer

file2

awesomepossum

file3

hownowbrowncow

실제로 uuencode & uudecode를 사용하여 비슷한 작업을 수행하고 있습니다. 파일을 읽을 필요가 없으며 결과 만 필요하며 다른 명령으로 다시 파이프해야합니다.

답변:


531

같은 것을 찾고 있었고 이것을 제안하는 것을 발견했습니다.

tail -n +1 file1.txt file2.txt file3.txt

산출:

==> file1.txt <==
<contents of file1.txt>

==> file2.txt <==
<contents of file2.txt>

==> file3.txt <==
<contents of file3.txt>

파일이 하나만 있으면 헤더가 인쇄되지 않습니다. GNU utils를 사용 -v하는 경우 항상 헤더를 인쇄하는 데 사용할 수 있습니다 .


2
이것은 GNU tail (GNU Coreutils의 일부)에서도 작동합니다.
ArjunShankar

7
멋진 -n +1옵션! 대안 : head -n-0 file1 file2 file3.
Frozen Flame

2
맥 OS X에서 당신에 모두 BSD 꼬리와 GNU 꼬리 훌륭한 작품 사이의 공간을 남길 수 -n+1같이 -n+1.
vdm

4
tail -n +1 *내가 찾던 것이 바로 고마워요!
kR105

1
MacOsX 10.14.4에서 작동sudo ulimit -n 1024; find -f . -name "*.rb" | xargs tail -n+1 > ./source_ruby.txt
kolas

186

비슷한 것을 위해 grep을 사용했습니다.

grep "" *.txt

'헤더'를 제공하지는 않지만 모든 줄 앞에 파일 이름을 붙입니다.


10
*.txt하나의 파일로만 확장 되면 출력이 중단됩니다 . 이와 관련하여 다음과 같이 조언합니다grep '' /dev/null *.txt
antak

1
grep의 새로운 사용법을 보여준 +1 이것은 나의 요구를 완벽하게 충족시켰다. 필자의 경우 각 파일에는 한 줄만 포함되어 있으므로 쉽게 분석 할 수있는 깔끔한 형식의 출력을 제공했습니다.
verboze

9
grep파일이 둘 이상인 경우 파일 헤더 만 인쇄합니다. 항상 파일 경로를 인쇄하려면을 사용하십시오 -H. 헤더를 원하지 않으면을 사용하십시오 -h. 또한 (standard input)STDIN 용으로 인쇄 됩니다.
Jorge Bucaran

1
ag(은색 검색기)를 사용할 수도 있습니다 . 기본적으로 ag . *.txt각 파일 앞에 이름과 접두사를 붙입니다.
anol

1
-ngrep에 전달 하면 행 번호가 생성되므로 emacs와 같이 집어 올릴 수있는 핀터 링으로 간단한 린터를 작성할 수 있습니다.
DepressionedDaniel

104

이것은 트릭을 수행해야합니다.

find . -type f -print -exec cat {} \;

방법:

find    = linux `find` command finds filenames, see `man find` for more info
.       = in current directory
-type f = only files, not directories
-print  = show found file
-exec   = additionally execute another linux command
cat     = linux `cat` command, see `man cat`, displays file contents
{}      = placeholder for the currently found filename
\;      = tell `find` command that it ends now here

당신은 더 부울 연산자 좋아 저점 검색을 결합 할 수 있습니다 -and또는 -or. find -ls역시 좋습니다.


1
이 명령의 기능에 대해 더 자세히 설명해 주시겠습니까? 정확히 내가 필요한 것
AAlvz

4
이것은 리눅스의 표준 찾기 명령입니다. 현재 디렉토리의 모든 파일을 검색하고 이름을 인쇄 한 다음 각 파일에 대해 파일을 표시합니다. 를 생략하면 -print파일 이름 앞에 파일 이름이 인쇄되지 않습니다 cat.
Maxim_united

17
-printf출력을 사용자 정의하는 데 사용할 수도 있습니다 . 예를 들면 다음 find *.conf -type f -printf '\n==> %p <==\n' -exec cat {} \;과 같습니다.tail -n +1 *
Maxim_united

1
-printf는 원하는 brew install findutils경우 gfind대신에 사용 하지 않으면 mac에서 작동하지 않습니다 find.
Matt Fletcher

1
당신이 색상을 원한다면 당신 find은 여러 가지 를 허용 하는 사실을 사용할 수 있습니다 -exec:find -name '*.conf' -exec printf '\n\e[33;1m%s\e[0m\n' {} \; -exec cat {} \;
banbh

24

트릭을 수행해야합니다.

for filename in file1.txt file2.txt file3.txt; do
    echo "$filename"
    cat "$filename"
done > output.txt

또는 모든 텍스트 파일에 대해 재귀 적 으로이 작업을 수행하십시오.

find . -type f -name '*.txt' -print | while read filename; do
    echo "$filename"
    cat "$filename"
done > output.txt

1
작동하지 않았다. 방금 정말 못생긴 awk 코드를 작성했습니다. concat.txt 완료
Nick

2
... 정교하게 신경써? 그것은 bash 코드가 얻는 것처럼 간단합니다.
크리스 에버 레

@Nick : $0전체 라인을 고려할 때 awk 라인이 작동하지 않아야 하므로 실제로 거기에 열이 반복됩니다.
Chris Eberle

@Nick : 그렇지 않으면 멋진 솔루션 :)
Chris Eberle

@Chris : 그렇습니다. 그러나 그것이 원하는 것보다 훨씬 더 나쁩니다. 내가 stdout을 잡기 위해 >>를 사용하고 있기 때문에 코드가 작동하지 않았을 수 있습니다.
Nick

17

파일 이름과 연결하려는 stats.txt로 끝나는 일련의 파일이 있습니다.

다음을 수행했으며 둘 이상의 파일이있을 때 "more"명령은 파일 이름을 헤더로 포함합니다.

more *stats.txt > stats.txt

또는 일반적인 경우

more FILES_TO_CONCAT > OUTPUT_FILE

5
more <FILES> | cat
Acumenus

15
find . -type f -print0 | xargs -0 -I % sh -c 'echo %; cat %'

전체 파일 이름 (경로 포함)을 인쇄 한 다음 파일 내용을 인쇄합니다. find 명령에 -name "expr"을 사용하고 파일에서 원하는만큼 많은 명령을 실행할 수 있으므로 매우 유연합니다.


1
와 결합하는 것도 매우 간단합니다 grep. 함께 사용하려면 bash:find . -type f -print | grep PATTERN | xargs -n 1 -I {} -i bash -c 'echo ==== {} ====; cat {}; echo'
dojuba

5

나는이 옵션을 좋아한다

for x in $(ls ./*.php); do echo $x; cat $x | grep -i 'menuItem'; done

출력은 다음과 같습니다.

./debug-things.php
./Facebook.Pixel.Code.php
./footer.trusted.seller.items.php
./GoogleAnalytics.php
./JivositeCode.php
./Live-Messenger.php
./mPopex.php
./NOTIFICATIONS-box.php
./reviewPopUp_Frame.php
            $('#top-nav-scroller-pos-<?=$active**MenuItem**;?>').addClass('active');
            gotTo**MenuItem**();
./Reviews-Frames-PopUps.php
./social.media.login.btns.php
./social-side-bar.php
./staticWalletsAlerst.php
./tmp-fix.php
./top-nav-scroller.php
$active**MenuItem** = '0';
        $active**MenuItem** = '1';
        $active**MenuItem** = '2';
        $active**MenuItem** = '3';
./Waiting-Overlay.php
./Yandex.Metrika.php

4

이것은 일반적으로 다음과 같은 형식을 처리하는 방법입니다.

for i in *; do echo "$i"; echo ; cat "$i"; echo ; done ;

나는 일반적으로 특정 정보를 위해 고양이를 grep으로 파이프합니다.


3
여기서 조심하십시오. for i in *하위 디렉토리는 포함하지 않습니다.
Acumenus


3

for 루프를 사용하는 대신이 간단한 명령을 사용할 수 있습니다.

ls -ltr | awk '{print $9}' | xargs head

3

색상이 마음에 들면 다음을 시도하십시오.

for i in *; do echo; echo $'\e[33;1m'$i$'\e[0m'; cat $i; done | less -R

또는:

tail -n +1 * | grep -e $ -e '==.*'

또는 : ( 'multitail'패키지가 설치된 경우)

multitail *

1
파일 이름을 강조하는 색상을 위해 :find . -type f -name "*.txt" | xargs -I {} bash -c "echo $'\e[33;1m'{}$'\e[0m';cat {}"
MediaVince

3

파일의 이름이 모두 같거나로 일치 할 수있는 경우 다음과 같은 find작업을 수행 할 수 있습니다.

find . -name create.sh | xargs tail -n +1

찾아 각 파일의 경로를 표시하고 고양이.


2

여기 정말 간단한 방법이 있습니다. 당신은 고양이를 원한다고 말했는데, 그것은 당신이 전체 파일을보고 싶다는 것을 의미합니다. 그러나 파일 이름도 인쇄해야합니다.

이 시도

head -n99999999 * 또는 head -n99999999 file1.txt file2.txt file3.txt

희망이 도움이


4
더 확실한 구문은입니다 head -n -0 file.txt file2.txt file3.txt. headGNU coreutils에서 작동
doubleDown

1

이 방법은 파일 이름을 인쇄 한 다음 파일 내용을 인쇄합니다.

tail -f file1.txt file2.txt

산출:

==> file1.txt <==
contents of file1.txt ...
contents of file1.txt ...

==> file2.txt <==
contents of file2.txt ...
contents of file2.txt ...

3
-f당신이 아니라 실제로 영업 이익은 무엇을 요구의 범위 내에서,에 기록되는 파일을 추적하려는 경우에 유용합니다.
tripleee

1

그 못생긴 ==> <==를 다른 것으로 바꾸려면

tail -n +1 *.txt | sed -e 's/==>/\n###/g' -e 's/<==/###/g' >> "files.txt"

설명:

tail -n +1 *.txt -헤더가있는 폴더의 모든 파일 출력

sed -e 's/==>/\n###/g' -e 's/<==/###/g'- 교체 ==>와 함께 새로운 라인 + ###<== 단지와 ###

>> "files.txt" -파일로 모두 출력



0

원하는 출력과 같은 형식으로 결과를 원하면 다음을 시도해보십시오.

for file in `ls file{1..3}.txt`; \
do echo $file | cut -d '.' -f 1; \ 
cat $file  ; done;

결과:

file1
bluemoongoodbeer
file2
awesomepossum
file3
hownowbrowncow

당신은 넣을 수 있습니다 echo -e당신은뿐만 아니라 라인 사이의 간격을 그래서 전에 절단 후 :

$ for file in `ls file{1..3}.txt`; do echo $file | cut -d '.' -f 1; echo -e; cat $file; echo -e  ; done;

결과:

file1

bluemoongoodbeer

file2

awesomepossum

file3

hownowbrowncow

설명 : forloop는 ls명령이 생성 한 목록을 통과합니다 . $ ls file{1..3}.txt결과 : file1.txt file2.txt file3.txt각 반복이됩니다 문자열 다음은에 파이프있어 내가 사용하는 명령 필드 1 밖으로 두 조각 및 인쇄 (FIELD2은 TXT입니다) 나머지는 명확해야에 fileX.txt를 나누기 필드 구분자로echo$filecut.
Fekete 수메르

0
  • AIX 7.1 ksh

... 이미 우리 중 일부를 위해 헤드 작업을 언급 한 사람들에게 빛을 발합니다 .

$ r head
head file*.txt
==> file1.txt <==
xxx
111

==> file2.txt <==
yyy
222
nyuk nyuk nyuk

==> file3.txt <==
zzz
$

내 필요는 첫 줄을 읽는 것입니다. 언급했듯이 10 줄 이상을 원하면 옵션 (head -9999 등)을 추가해야합니다.

파생 의견을 게시 해 주셔서 감사합니다. 다른 사람의 댓글에 댓글을 달거나 추가 할 충분한 거리 정보가 없습니다.


-1

이 작업을 해결하기 위해 일반적으로 다음 명령을 사용합니다.

$ cat file{1..3}.txt >> result.txt

파일 수가 매우 많은 경우 파일을 연결하는 매우 편리한 방법입니다.


1
그러나 이것은 OP의 질문에 대답하지 않습니다.
kvantour

-3

먼저 각 파일을 만들었습니다 : echo 'information'> file1.txt 각 파일 [123] .txt.

그런 다음 각 파일을 인쇄하여 정보가 올바른지 확인하십시오 : tail file? .txt

그런 다음이 작업을 수행했습니다 : tail file? .txt >> Mainfile.txt. Mainfile.txt를 생성하여 각 파일의 정보를 기본 파일에 저장했습니다.

cat Mainfile.txt가 정상임을 확인했습니다.

==> file1.txt <== bluemoongoodbeer

==> file2.txt <== awesomepossum

==> file3.txt <== hownowbrowncow

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